构成 setter 镜头的语法是什么?
What is the syntax for composing setter lenses?
我是 lens 的新手,我想编写两个 "setter" 操作等效于此状态 0 到 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
不过,在您的示例中,您不想合成镜头;你想组合transformations(既是镜头又是实际操作),有两种方法可以做到。
哦,在我们真正开始之前,让我们稍微简化一下您的代码,使用 (.~)
("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
以获得更多可用效果二传手。
我是 lens 的新手,我想编写两个 "setter" 操作等效于此状态 0 到 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
不过,在您的示例中,您不想合成镜头;你想组合transformations(既是镜头又是实际操作),有两种方法可以做到。
哦,在我们真正开始之前,让我们稍微简化一下您的代码,使用 (.~)
("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
以获得更多可用效果二传手。