Is there a Lens/Optic that can use to dig deeply into multidimensional maps?

Viewed 95

I've had a bit of difficulty using Lenses with Maps. I have maps that look like this Map String (Map String Int). These are multidimensional arrays, and I usually set them up with known dimensions. I often want to read and update elements of these Maps, but not add or delete elements.

I want an optic, similar to ix "k1" . ix "k2" that allowed me to do the following:

myfunc :: Map String (Map String Int) -> ()
myfunc m =
  let m' = m & ix "k1" . ix "k2" %~ (+1)
      v = m ^. ix "k1" . ix "k2"
  in () 

Unfortunately, I can't use ix "k1" . ix "k2" because the v = m ^. ix "k1" . ix "k2" won't compile because Int isn't a Monoid. In general, I can't have this Monoid restriction because I generally hold fairly complex values in my maps (like some complex state ADT). (I'm guessing this Monoid restriction is there so that ix can return a default value if the key doesn't exist.) I want an optic without this Monoid restriction and that would just throw a fatal error if I try indexing with a key that doesn't exist. Is it possible to create such a thing on my own?

0 Answers
Related