Haskell Control.Lens Traversing Prism

У меня глубоко вложенная структура данных, и я использую Control.Lens.*, Чтобы упростить доступ к его значениям в монаде состояния.

Итак, рассмотрим следующее:

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

$(makeLenses ''Config)

Как мне работать "функториально" над "Возможно"? Я хотел бы написать идиоматический геттер, который делает:

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?

1 ответ

Решение

Вы хотите использовать Prism чтобы (возможно) пойти в Just ветка.

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

И тогда это Prism будет составлять так же, как и другие линзы, образуя Traversals.

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

Другие вопросы по тегам