Haskell,只修改一个结构域

Posted

技术标签:

【中文标题】Haskell,只修改一个结构域【英文标题】:Haskell, modyfying only one field of structure 【发布时间】:2017-01-06 07:11:45 【问题描述】:

我有一些结构:

data S =  
  a :: Integer,
  b :: Integer,
  c :: String,
  d :: Map String Integer
   

我在我的State monad 中关闭了它,我正在以下列方式使用它:

s <- get
let S a = a', b =b', c=c', d=d' s   
put $ S a = a' + 1, b = b', c= c', d = d'   

如您所见,当我只想修改/读取一个字段(此处为a)时,我必须获取并放置所有字段 - 这很尴尬 - 否则我会收到警告,有时还会出现运行时错误。

您能否尝试向我提出一些解决方案以使其更好更清洁?

提前致谢, 问候

【问题讨论】:

【参考方案1】:

您可以使用记录更新并仅指定要更新的字段。此外,您可以在模式匹配期间提取特定字段。

s@S a = a'  <- get 
put $ s a = a' + 1  

或者,如果您发现自己做了很多此类事情,您可能想要使用lens。使用lens,您必须为S 制作镜头(这需要打开-XTemplateHaskell

data S =  _a, _b :: Integer, _c :: String, _d :: Map String Integer 
makeLenses ''S

但是,在你的状态单子中,你可以写

a += 1

是的,这是合法的 Haskell。 +=其实是一个东西。

【讨论】:

以上是关于Haskell,只修改一个结构域的主要内容,如果未能解决你的问题,请参考以下文章

Haskell - 要么只映射一个

haskell的结构归纳

为啥我修改后的(真实世界的haskell)Mapreduce 实现失败并显示“打开的文件太多”

Haskell 持久列表

Haskell, Types, Tests

Haskell中的两个无限数据结构之间是不是可以进行相等测试?