ekmett / lens

Lenses, Folds, and Traversals - Join us on web.libera.chat #haskell-lens
http://lens.github.io/
Other
2.03k stars 273 forks source link

Document Ixed restriction #662

Open treeowl opened 8 years ago

treeowl commented 8 years ago

Along with the general law that ix should produce a valid Traversal, I suspect we also want to require that ix never use the <*> it gets from the Applicative constraint. Conceptually, it should only need Pointed. I believe this follows from the Ixed/At relationship when we have At.

treeowl commented 8 years ago

This would rule out an ix that traverses all values associated with a single key in a multimap, requiring it to produce a single container with all of them. Of course, it's also possible that such a thing should be considered valid. In any case, some clarity would be nice.

ghost commented 8 years ago

I can't think of any reason to disallow it, although I'm not sure that, in the case of a multimap, it would be particularly useful.

treeowl commented 8 years ago

One reason to disallow it is to allow Ixed users to rely on an ix traversal traversing at most one element. This allows fake Applicatives:

newtype Fudge f a = Fudge (f a)
instance Pointed f => Applicative (Fudge f) where
  pure = Fudge . point
  _ <*> _ = error "Not really Applicative"

ix' :: (Ixed m, Pointed f) => Index m -> (IxValue m -> f (IxValue m)) -> m -> f m
ix' = ... -- Use Fudge.

The downside, of course, is that someone might want their Ixed instance to traverse multiple values. If that's permitted, I think it might be nice to add an example of such an instance to the documentation.