Как увеличить кислотное состояние?

data Foo = Foo {
  _bar :: Map String Integer
} deriving (Eq, Ord, Read, Show, Data, Typeable)

$(deriveSafeCopy 0 'base 'Foo)

$(makeLenses ''Foo)

Учитывая приведенный выше код, у меня сложилось впечатление, что это должно быть возможно:

addEntry :: String -> Update Foo ()
addEntry s = zoom bar $ modify $ insert s 0

Но GHC будет жаловаться на:

src/Backend.hs:39:20:
    No instance for (Functor
                       (Control.Lens.Internal.Zoom.Zoomed (Update Foo) ()))

Любые идеи?


person fho    schedule 19.12.2013    source источник


Ответы (1)


Control.Lens.Internal.Zoom.Zoomed - это семейство типов, которое описывает, какой контекст требуется во время zoom. Он выполняет особую магию, как вы можете видеть в Control.Lens.Internal.Zoom модуль. Обычно пользователю zoom никогда не нужно это видеть, пока он увеличивает "типичный" стек преобразователя монад.

Update, хотя и реализован как State под крышками, не имеет экземпляра масштабирования. Его реализация также не экспортируется, поэтому вы не можете написать свою собственную, хотя это было бы довольно тривиально, поскольку Update не использует преобразователи монад.

type instance Zoomed (Update x) = Focusing Identity
person J. Abrahamson    schedule 19.12.2013
comment
Так что, вероятно, нет способа поместить это (и подобные экземпляры) в какой-нибудь пакет, например lens-acidstate? - person fho; 20.12.2013
comment
Потребовалось бы еще несколько хитрых манипуляций с модулями - вероятно, acidstate-internal, от которого будут зависеть как acidstate, так и lens-acidstate. - person J. Abrahamson; 20.12.2013
comment
Стоило ли оно того? Или есть способ предоставить Zoomed, не полагаясь на lens, поскольку это возможно с базовыми Lens типами? (Этот вопрос, вероятно, следует адресовать непосредственно ekmett или специалистам по обслуживанию кислотного состояния.) - person fho; 25.12.2013