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

$(deriveSafeCopy 0 'base 'Foo)

$(makeLenses ''Foo)

Given the above code I am under the impression that it should be possible to do this:

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

But GHC will complain along the lines of:

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

Any ideas?

fho
  • 6,787
  • 26
  • 71

1 Answers1

8

Control.Lens.Internal.Zoom.Zoomed is a type family which describes what kind of context is required during a zoom. It performs some special magic as you can see in the Control.Lens.Internal.Zoom module. Typically a user of zoom would never need to see that stuff so long as they zoom in on a "typical" monad transformer stack.

Update, while being implemented as just State beneath the covers, doesn't have a zoom instance. Its implementation is not exported either so you're unable to write your own, though it'd be quite trivial since Update doesn't use monad transformers.

type instance Zoomed (Update x) = Focusing Identity
J. Abrahamson
  • 72,246
  • 9
  • 135
  • 180
  • So there is probably no way to get this (and similar instances) into some package like `lens-acidstate`? – fho Dec 20 '13 at 10:15
  • It'd require some more sneaky module juggling—probably an `acidstate-internal` which both `acidstate` and `lens-acidstate` would depend upon. – J. Abrahamson Dec 20 '13 at 14:18
  • 2
    Would it be worth it? Or is there a way to provide `Zoomed` without relying on `lens` as it is possible with the basic `Lens` types? (This question should probably directed directly to ekmett or the acid-state maintainers.) – fho Dec 24 '13 at 21:35