组合定位镜头的语法是什么?

时间:2016-05-20 21:00:24

标签: haskell setter lens lenses

我是镜片的新手,我想写两个" setter"操作等同于state0到new_state2转换:

ngIf

这样做的语法是什么?

1 个答案:

答案 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的效果。