gpt4 book ai didi

haskell - Haskell 是否有指向记录成员的指针/引用?

转载 作者:行者123 更新时间:2023-12-02 15:57:35 24 4
gpt4 key购买 nike

我可以使用 ::*.*->* 语法在 C++ 中创建和引用指向结构成员的相对指针像:

char* fstab_t::*field = &fstab_t::fs_vfstype;
my_fstab.*field = ...

在 Haskell 中,我可以轻松地为记录 getter 创建临时标签,例如:

(idxF_s,idxL_s) = swap_by_sign sgn (idxF,idxL) ;

Afaik,但是我无法使用这些 getter 作为标签来更新记录,例如:

a { idxF_s = idxL_s b }

有没有一种简单的方法可以做到这一点,而无需为每个记录设置者编码?

最佳答案

在一流值中捆绑在一起的 getter 和 setter 称为透镜。有很多包可以做到这一点;最受欢迎的是 data-lensfclabels 。这个previous SO question是一个很好的介绍。

这两个库都支持使用 Template Haskell 从记录定义中派生镜头(对于数据镜头,为了可移植性,它以 an additional package 的形式提供)。您的示例将表示为(使用数据透镜语法):

setL idxF_s (b ^. idL_s) a

(或等效:idxF_s ^= (b ^.idL_s) $ a)

当然,您可以通过将镜头的 getter 和 setter 一起转换来以通用方式转换镜头:

-- I don't know what swap_by_sign is supposed to do.
negateLens :: (Num b) => Lens a b -> Lens a b
negateLens l = lens get set
where
get = negate . getL l
set = setL l . negate

(或等效:negateLens l = iso negate negate .l1)

一般来说,每当您需要处理任何类型的重要记录处理时,我都会建议使用镜头;它们不仅极大地简化了记录的纯粹转换,而且两个包都包含使用镜头访问和修改状态单子(monad)状态的便利函数,这非常有用。 (对于数据透镜,您需要使用 data-lens-fd 包在任何 MonadState 中使用这些便利函数;同样,为了可移植性,它们位于单独的包中。)

<小时/>

1 使用任一包时,您应该使用以下命令启动模块:

import Prelude hiding (id, (.))
import Control.Category

这是因为它们使用 Prelude 的 id(.) 函数的通用形式 — id 可以用作任何值本身(诚然,并不是那么有用),并且 (.) 用于组成镜头(例如 getL (fieldA . fieldB) a 相同>getL 字段A . getL 字段B $ a)。较短的 negateLens 定义使用此。

关于haskell - Haskell 是否有指向记录成员的指针/引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9144023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com