lef*_*out 6 haskell arrows lenses haskell-lens
import Control.Lens
import Control.Lens.TH
data Foo = Foo {
_bar, _baz :: Int
}
makeLenses ''Foo
Run Code Online (Sandbox Code Playgroud)
现在,如果我想修改两个int字段,我可以做
barbaz :: Setter' Foo Int
barbaz = sets $ \foo f -> foo & bar %~ f
& baz %~ f
Run Code Online (Sandbox Code Playgroud)
但这似乎是一种非常难看的手动方式.
使用镜头/箭头组合器可以直接实现吗?
我以前遇到过这个问题,并且有一个适用于两个镜头的解决方案,将它们组合成一个遍历:
fields2 :: Lens' s a -> Lens' s a -> Traversal' s a
fields2 f1 f2 f s = (\v1 v2 -> s & f1 .~ v1 & f2 .~ v2) <$> f (s ^. f1) <*> f (s ^. f2)
barbaz = fields2 bar baz
Run Code Online (Sandbox Code Playgroud)
这可以像这样使用:
foo & barbaz %~ f
Run Code Online (Sandbox Code Playgroud)
它有点脏并且无法扩展,但它对我有用:D 如果有人发布更好的答案,我会很高兴!