我有一个深度嵌套的数据结构,我正在使用Control.Lens。*来简化在状态monad中访问它的值。
请考虑以下事项:
data Config = Config { _foo :: Maybe Int
, _bar :: Int
}
$(makeLenses ''Config)
如何对“可爱”进行“有趣”操作?我想写一个惯用的getter:
config = Config (Just 1) 0
config^.foo.to fmap (+1) == Just 2
更好的是,当Config嵌套得更深时,我们将如何处理这种情况?
data Config = { _foo :: Maybe Foo }
data Foo = Foo { _bar :: Bar }
data Bar = Bar Int
$(makeLenses ''Bar)
$(makeLenses ''Foo)
我们可以使用访问器foo和bar来返回修改后的Bar吗?
答案 0 :(得分:13)
您希望使用Prism
(可能)进入Just
分支。
>>> let config' = config & foo . _Just .~ (+1)
in config' ^. foo
Just 2
然后这个Prism
将与其他镜头组成一样,形成Traversal
s。
foo . _Just . bar . _Bar :: Traversal' Config Int
看一下我在镜头上写的一些教程,花一点时间来研究Lens
和Prism
之间的关系:
https://www.fpcomplete.com/user/tel/a-little-lens-starter-tutorial
https://www.fpcomplete.com/user/tel/lens-aeson-traversals-prisms