我是Lens的新手,我想编写两个“ setter”操作来等效于从state0到new_state2的转换:
let new_state1 = field1 %~ (const newVal1) $ state0
let new_state2 = field2 %~ (const newVal2) $ new_state1
这样做的语法是什么?
有趣的是,镜头像功能一样组成:带有(.)
:
setterAB :: Lens' A B
setterBC :: Lens' B C
setterAC = setterAB . setterBC
但是,在您的示例中,您不想构图。您想组成变换(既是镜头又是实际操作),有两种方法可以实现。
哦,在我们真正理解这一点之前,让我们使用(.~)
(“ set”)而不是(%~)
(“ modify”)来简化您的代码:
let new_state1 = field1 .~ newVal1 $ state0
let new_state2 = field2 .~ newVal2 $ new_state1
有一个&
很好的运算符,效果很好。只是flip ($)
:
let new_state1 = state0 & field1 .~ newVal1
let new_state2 = new_state & field2 .~ newVal2
这意味着您现在可以编写:
let new_state =
state0
& field1 .~ newVal1
& field2 .~ newVal2
甚至更好的是,如果您实际上在State
某个地方,可以完全摆脱过去的传递并将其放到monad中:
let new_state = (flip execState state0) $ do
field1 .= newVal1
field2 .= newVal2
它们是根据定义的MonadState
,因此,如果您位于monad堆栈中,则可以直接使用该实例,也可以使用StateT
来获取给二传手可用的更多效果。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句