ekmett / bifunctors

Haskell 98 bifunctors, bifoldables and bitraversables
Other
57 stars 42 forks source link

Bicayley #67

Open Icelandjack opened 6 years ago

Icelandjack commented 6 years ago

Does this belong anywhere? Just as we have Cayley

newtype Cayley f p a b = Cayley (f (p a b))

instance (Applicative f, Category p) => Category (Cayley f p) where

we can have

newtype Bicayley f p q a b = Bicayley (f (p a b) (q a b))

instance (Biapplicative f, Category p, Category q) => Category (Bicayley f p q) where
  id = Bicayley (bipure id id)
  Bicayley f . Bicayley g = Bicayley (biliftA2 (.) (.) f g)

No use cases personally.

bb010g commented 4 years ago

No uses case for Bicayley as named also, but just ran into a similar desire for Bitannen.

Tannen has the same shape

newtype Tannen f p a b = Tannen { runTannen :: f (p a b) }

instance (Applicative f, Category p) => Category (Tannen f p) where
  id = Tannen $ pure id
  Tannen fpbc . Tannen fpab = Tannen $ liftA2 (.) fpbc fpab

-- for comparison of Category implementations
instance (Applicative f, Category p) => Category (Cayley f p) where
  id = Cayley $ pure id
  Cayley fpbc . Cayley fpab = Cayley $ liftA2 (.) fpbc fpab

and I'd imagine has a similar Category instance.

I don't know the math behind Cayley; what's the difference between it & Tannen, besides situation next to Profunctor? Profunctor obviously is shaped similarly to Bifunctor, but Cayley doesn't seem to have any particular attachment to Profunctor, and the instances common to Tannen also share implementations.

treeowl commented 3 years ago

@bb010g , I think the main difference is the expectation of what p is. For Cayley it's expected to be a Category whereas for Tannen it's expected to be a Bifunctor. These are rather different beasts.