我有一个深度嵌套的数据结构,我使用 Control.Lens.* 来简化在 state monad 中访问它的值。

因此,请考虑以下事项:

data Config = Config { _foo :: Maybe Int
                     , _bar :: Int
                     }

$(makeLenses ''Config)

我如何在Maybe上“功能性地”操作?我想写一个惯用的 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 吗?

最佳答案

你会想要使用 Prism 来(也许)进入 Just 分支。

>>> let config' = config & foo . _Just .~ (+1)
    in  config' ^. foo
Just 2

然后这个 Prism 将与其他镜头一样组成,形成 Traversal s。
foo . _Just . bar . _Bar :: Traversal' Config Int

看看我在镜头上写的一些教程,这些教程花了一些时间研究 LensPrism 之间的关系:

https://www.fpcomplete.com/user/tel/a-little-lens-starter-tutorial

https://www.fpcomplete.com/user/tel/lens-aeson-traversals-prisms

关于Haskell Control.Lens 横穿棱镜,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19555961/

10-11 04:07