Haskell Control.Lens遍历棱镜

nom*_*men 4 haskell lenses haskell-lens

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

请考虑以下事项:

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

$(makeLenses ''Config)
Run Code Online (Sandbox Code Playgroud)

如何在"可爱"上"操作"地操作?我想写一个惯用的吸气剂:

config = Config (Just 1) 0
config^.foo.to fmap (+1) == Just 2
Run Code Online (Sandbox Code Playgroud)

更好的是,当Config嵌套得更深时,我们将如何处理这种情况?

data Config = { _foo :: Maybe Foo }
data Foo = Foo { _bar :: Bar }
data Bar = Bar Int
$(makeLenses ''Bar)
$(makeLenses ''Foo)
Run Code Online (Sandbox Code Playgroud)

我们可以使用访问器foo和bar来返回修改后的Bar吗?

J. *_*son 13

你会想用a Prism(也许)进入Just分支.

>>> let config' = config & foo . _Just .~ (+1)
    in  config' ^. foo
Just 2
Run Code Online (Sandbox Code Playgroud)

然后这Prism将构成与其他镜头相同,形成Traversals.

foo . _Just . bar . _Bar :: Traversal' Config Int
Run Code Online (Sandbox Code Playgroud)

看看我在镜头上写的一些教程,花一点时间研究如何LensPrism关联:

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

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