我是镜片的新手,我想写两个" setter"操作等同于state0到new_state2转换:
ngIf
这样做的语法是什么?
答案 0 :(得分:6)
有趣的是,镜头就像功能一样:使用(.)
:
setterAB :: Lens' A B
setterBC :: Lens' B C
setterAC = setterAB . setterBC
在你的例子中,你不想构图镜头;你想组成转换(这是镜头和实际操作),有两种方法可以做到。
哦,在我们实际开始之前,让我们使用(.~)
(“set”)代替(%~)
(“修改”)来简化代码:
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
以获得更多可用于setter的效果。