ekmett / adjunctions

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

Day instances derived from from Compose #43

Closed Icelandjack closed 6 years ago

Icelandjack commented 7 years ago

There is an isomorphism between Compose f g and Day f g of representable functors

c2d :: (Representable f, Representable g) => Compose f g a -> Day f g a
c2d = tabulate . index

d2c :: (Representable f, Representable g) => Day f g a -> Compose f g a
d2c = tabulate . index

This means every instance of Compose f g is a potential instance for Day, would these instances be useful and worth adding?

instance (Alternative f, Representable f, Alternative g, Representable g) => Alternative (Day f g) where
  empty :: Day f g a 
  empty  = c2d empty

  (<|>) :: Day f g a -> Day f g a -> Day f g a
  (d2c -> a) <|> (d2c -> b) = c2d (a <|> b)

This allows for an Alternative definition as well as an inordinate number of other instances.


We also get a handful of classes the other way: some instance for Compose f g that work for functors like Coyoneda f, (_ ->), Cofree, Day and recursively Compose (it would be an orphan instance I suppose)

instance (Comonad f, Representable f, Comonad g, Representable g) => Comonad (Compose f g) where
  extract :: Compose f g a -> a
  extract = extract . c2d

  duplicate :: Compose f g a -> Compose f g (Compose f g a)
  duplicate = fmap d2c . d2c . duplicate . c2d 

instance (ComonadApply f, ComonadApply g, Representable g, Representable f) => ComonadApply (Compose f g) where
  (<@>) :: Compose f g (a -> b) -> (Compose f g a -> Compose f g b)
  (c2d -> f) <@> (c2d -> x) = d2c (f <@> x)
sjoerdvisscher commented 7 years ago

Any Alternative functor f must have an empty shape to provide an f a for any a. Representable functors only have one shape, so an Alternative Representable functor must be isomorphic to Void. So at least that instance is not very interesting.

Icelandjack commented 6 years ago

Good observation (it was a pleasure meeting you at Haskell eXchange @sjoerdvisscher)

Other instances may be mildly interesting but should really be derived through DerivingVia rather than fixing them as an instance.

newtype M33 a = M33 (V3 (V3 a))
  deriving 
    (Generic, Generic1)
  deriving (Comonad, ...)
    via (Compose V3 V3 `STEALING` Day V3 V3)

I think I will close this ticket