Haskell,只有一个结构域

时间:2017-01-06 07:11:45

标签: haskell

我有一些结构:

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 个答案:

答案 0 :(得分:7)

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

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

但是,在你的州monad你可以写

a += 1

是的,这是合法的Haskell。 +=实际上是一件事。