I have a deeply nested data structure, and I'm using Control.Lens.* to simplify accessing its values in a state monad.
So consider the following:
data Config = Config { _foo :: Maybe Int
, _bar :: Int
}
$(makeLenses ''Config)
How do I operate "functorially" over the Maybe? I'd like to write an idiomatic getter that does:
config = Config (Just 1) 0
config^.foo.to fmap (+1) == Just 2
Better still, how would we handle the case when Config is nested deeper?
data Config = { _foo :: Maybe Foo }
data Foo = Foo { _bar :: Bar }
data Bar = Bar Int
$(makeLenses ''Bar)
$(makeLenses ''Foo)
Can we use the accessors foo and bar to Maybe return a modified Bar?
You'll want to use a Prism
to (maybe) go into the the Just
branch.
>>> let config' = config & foo . _Just .~ (+1)
in config' ^. foo
Just 2
And then this Prism
will compose just the same as other lenses, forming Traversal
s.
foo . _Just . bar . _Bar :: Traversal' Config Int
Take a look at some tutorials I wrote on lens that spend a little time examining how Lens
and Prism
relate:
https://www.fpcomplete.com/user/tel/a-little-lens-starter-tutorial
https://www.fpcomplete.com/user/tel/lens-aeson-traversals-prisms
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With