ekmett / adjunctions

Simple adjunctions
http://hackage.haskell.org/package/adjunctions
Other
44 stars 27 forks source link

Add FunctorWithIndex constraint to Representable? #31

Open treeowl opened 8 years ago

treeowl commented 8 years ago
defaultimap ::
  Representable f => (Rep f -> a -> b) -> f a -> f b
defaultimap f fa = tabulate (f <*> index fa)

proves that we can (modulo package issues) use

class (FunctorWithIndex (Rep f) f, Distributive f) => Representable f where ...

The only potential downside (aside from package dep and compatibility issues) is that someone could theoretically use something other than Rep f as the index. This seems a bit unlikely, but not entirely impossible.

As for the packaging, I think it's weird that XxxWithIndex live in lens. Are the lensy defaults really worth tying these simple classes up with the behemoth?

RyanGlScott commented 8 years ago

Aside from the packaging issues (which are significant), it does feel odd to make single out FunctorWithIndex here, especially since Representable could also theoretically have Applicative, Monad, MonadFix, MonadZip, MonadReader, or Comonad as superclasses, but it doesn't. There's also https://github.com/ekmett/distributive/issues/12 to consider—that is, the issue of what superclasses to give Distributive.

In any case, I'll defer any decision about superclass engineering to @ekmett.

ekmett commented 8 years ago

I'm pretty negative on this one.

From a practical standpoint, this would cause a pretty awful upheaval in terms of where everything gets hosted. FunctorWithIndex lives in lens of all places. keys offered an older equivalent but far less useful class with fewer instances in a place where many useful instances have to be dropped and is very much on life support and not a hub of active development.

From a theory standpoint breaking Representable up into Distributive, Sieve, etc. or the equivalent offers a category theoretic justification. FunctorWithIndex is comparatively a rather unprincipled (if useful) hack with no guarantees about 'uniqueness' of keys.

Worse, as a bit of both, there are cases where the most usable form of key for FunctorWithIndex isn't the same as the key used by Representable. An example that comes to mind is V n a in linear, where we originally required keys to be drawn from a Fin n type, but the experience for users was absolutely awful.