我刚接触镜头(Lens)技术,我想将两个“setter”操作组合起来,使其等效于从state0到new_state2的转换:
let new_state1 = field1 %~ (const newVal1) $ state0
let new_state2 = field2 %~ (const newVal2) $ new_state1
这该怎么做的语法是什么?
我刚接触镜头(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
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
,你可以完全摆脱那个传递,并将其放入单子中:
let new_state = (flip execState state0) $ do
field1 .= newVal1
field2 .= newVal2
它们是基于MonadState
定义的,因此如果您在一个monad堆栈中,您可以直接使用那个实例,或者使用StateT
以便为setter提供更多的效果。