Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Every monad is an applicative functor — generalizing to other categories

I can readily enough define general Functor and Monad classes in Haskell:

class (Category s, Category t) => Functor s t f where
    map :: s a b -> t (f a) (f b)

class Functor s s m => Monad s m where
    pure :: s a (m a)
    join :: s (m (m a)) (m a)
    join = bind id
    bind :: s a (m b) -> s (m a) (m b)
    bind f = join . map f

I'm reading this post which explains an applicative functor is a lax (closed or monoidal) functor. It does so in terms of a (exponential or monoidal) bifunctor. I know in the Haskell category, every Monad is Applicative; how can we generalize? How should we choose the (exponential or monoidal) functor in terms of which to define Applicative? What confuses me is our Monad class seems to have no notion whatsoever of the (closed or monoidal) structure.

Edit: A commenter says it is not generally possible, so now part of my question is where it is possible.

like image 616
M Farkas-Dyck Avatar asked Dec 27 '18 16:12

M Farkas-Dyck


People also ask

Is every monad a functor?

As I understand, every monad is a functor but not every functor is a monad. A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value).

Are all monads applicative?

Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.

Is a monad applicative?

An applicative is a data type that implements the Applicative typeclass. A monad is a data type that implements the Monad typeclass. A Maybe implements all three, so it is a functor, an applicative, and a monad.

Is applicative a functor?

Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory. Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.

What is the difference between a monad and an applicative functor?

So a monad exists within a particular monoidal category (which happens to be a category of endofunctors), while an applicative functor maps between two monoidal categories (which happen to be the same category, hence it's a kind of endofunctor). Show activity on this post.

What are collection monads in category theory?

^ Category theory views these collection monads as adjunctions between the free functor and different functors from the category of sets to the category of monoids. ^ Here the task for the programmer is to construct an appropriate monoid, or perhaps to choose a monoid from a library.

What are the return and bind functions of a monad?

The return and bind function are: . From the category theory point of view, a state monad is derived from the adjunction between the product functor and the exponential functor, which exists in any cartesian closed category by definition. A continuation monad [o] with return type R maps type T into functions of type .

What is a monad type?

In addition to defining a wrapping monadic type, monads define two operators: one to wrap a value in the monad type, and another to compose together functions that output values of the monad type (these are known as monadic functions ).


2 Answers

What confuses me is our Monad class seems to have no notion whatsoever of the (closed or monoidal) structure.

If I understood your question correctly, that would be provided via the tensorial strength of the monad. The Monad class doesn't have it because it is intrinsic to the Hask category. More concretely, it is assumed to be:

t :: Monad m => (a, m b) -> m (a,b)
t (x, my) = my >>= \y -> return (x,y) 
like image 110
Jorge Adriano Avatar answered Sep 30 '22 04:09

Jorge Adriano


Essentially, all the monoidal stuff involved in the methods of a monoidal functor happens on the target category. It can be formalised thus:

class (Category s, Category t) => Functor s t f where
  map :: s a b -> t (f a) (f b)

class Functor s t f => Monoidal s t f where
  pureUnit :: t () (f ())
  fzip :: t (f a,f b) (f (a,b))

s-morphisms only come in if you consider the laws of a monoidal functor, which roughly say that the monoidal structure of s should be mapped into this monoidal structure of t by the functor.

Perhaps more insightful is to factor an fmap into the class methods, so it's clear what the “func-”-part of the functor does:

class Functor s t f => Monoidal s t f where
  ...
  puref :: s () y -> t () (f y)
  puref f = map f . pureUnit
  fzipWith :: s (a,b) c -> t (f a,f b) (f c)
  fzipWith f = map f . fzip

From Monoidal, we can get back our good old Hask-Applicative thus:

pure :: Monoidal (->) (->) f => a -> f a
pure a = puref (const a) ()

(<*>) :: Monoidal (->) (->) f => f (a->b) -> f a -> f b
fs <*> xs = fzipWith (uncurry ($)) (fs, xs)

or

liftA2 :: Monoidal (->) (->) f => (a->b->c) -> f a -> f b -> f c
liftA2 f xs ys = fzipWith (uncurry f) (xs,ys)

Perhaps more interesting in this context is the other direction, because that shows us up the connection to monads in the generalised case:

instance Applicative f => Monoidal (->) (->) f where
  pureUnit = pure
  fzip = \(xs,ys) -> liftA2 (,) xs ys
       = \(xs,ys) -> join $ map (\x -> map (x,) ys) xs

That lambdas and tuple sections aren't available in a general category, however they can be translated to cartesian closed categories.


I'm using (,) as the product in both monoidal categories, with identity element (). More generally you might write data I_s and data I_t and type family (⊗) x y and type family (∙) x y for the products and their respective identity elements.

like image 41
leftaroundabout Avatar answered Sep 30 '22 04:09

leftaroundabout