ekmett / distributive

Dual Traversable
http://hackage.haskell.org/package/distributive
Other
41 stars 25 forks source link

Sorta representable #48

Open treeowl opened 6 years ago

treeowl commented 6 years ago

As we've discussed, everything Distributive should be Representable, but maybe the librarian doesn't want to commit to a particular Rep. I just realize that there's actually a way to get a sort of middle ground, though it's a bit awkward.

class Functor f => Distributive f where
  data family RepD f -- Must be a newtype if Representable
  tabulateD :: (RepD f -> a) -> f a
  indexD :: f a -> RepD f -> a

class (Distributive f, Coercible (Rep f) (RepD f) => Representable f where
  type Rep f

tabulate :: forall f a. Representable f => (Rep f -> a) -> f a
tabulate = coerce (tabulateD :: (RepD f -> a) -> f a)

index :: forall f a. Representable f => f a -> Rep f -> a
index = coerce (indexD :: f a -> RepD f -> a)

If the module defining f chooses not to export the RepD f newtype constructor, then the choice of representation is hidden.