DEV Community

Molossus Spondee
Molossus Spondee

Posted on

Free monoidal functors in arbitrary categories

It is often joked "a monad is a monoid in the category of endofunctors."

Little known fact, an Applicative functor is a monoid in the category of functors with day convolution as the product.

And day convolution unlike endofunctor composition can be defined over any strong monoidal category (basically just has tuples and functions.)

Hence

{-# LANGUAGE ExistentialQuantification, RankNTypes #-}
import Prelude hiding (Functor (..), Applicative (..))
class Functor f where
  fmap :: Hom a b -> f a -> f b
class Functor f => Monoidal f where
  pure :: Id a -> f a
  join :: Day f f a -> f a
data Day f g a = forall x y. Day (f x) (g y) (Hom (PRODUCT x y) a)
instance Functor (Day f g) where
   fmap f (Day h x y) = Day (f :.: h) x y
data Id a = Id (forall x. Hom x a)
instance Functor Id where
    fmap f (Id x) = Id (f :.: x)
data Free f a = Pure (Id a) | Ap (Day f (Free f) a)
instance Functor (Free f) where
   fmap f (Pure x) = Pure (fmap f x)
   fmap f (Ap x) = Ap (fmap f x)
instance Monoidal (Free f) where
   pure = Pure
   join (Day h (Pure x) y) = Ap h x y

Where PRODUCTand Hom are up to you to define.

In order to have full applicative functors you need functions which your category might not have.

Top comments (0)