Tony Morris tonymorris at gmail.com
Wed Oct 24 08:22:21 CEST 2012

```As a side note, I think a direct superclass of Functor for Monad is not
a good idea, just sayin'

class Functor f where
fmap :: (a -> b) -> f a -> f b

class Functor f => Apply f where
(<*>) :: f (a -> b) -> f a -> f b

class Apply f => Bind f where
(=<<) :: (a -> f b) -> f a -> f b

class Apply f => Applicative f where
unit :: a -> f a

class (Applicative f, Bind f) => Monad f where

Same goes for Comonad (e.g. [] has (=<<) but not counit)
... and again for Monoid, Category, I could go on...

On 17/10/12 04:14, David Thomas wrote:
> I think the version below (with a Functor or Applicative superclass)
> is clearly the right answer if we were putting the prelude together
> from a clean slate.  You can implement whichever is easiest for the
> particular monad, use whichever is most appropriate to the context
> (and add optimized versions if you prove to need them).  I see no
> advantage in any other specific proposal, except the enormous
>
> Regarding mathematical "purity" of the solutions, "this is in every
> way isomorphic to a monad, but we aren't calling it a monad because we
> are describing it a little differently than the most common way to
> describe a monad in category theory" strikes me as *less*
> mathematically grounded than "we are calling this a monad because it
> is in every way isomorphic to a monad."
>
> On Tue, Oct 16, 2012 at 7:03 AM, AUGER Cédric <sedrikov at gmail.com> wrote:
>> So I think that an implicit question was why wouldn't we have:
>>
>>   return :: a -> m a
>>   kleisli :: (a -> m b) -> (b -> m c) -> (a -> m c)
>>   bind = \ x f -> ((const x) >=> f) ()
>>   join = id>=>id :: (m (m a) -> m a)
>> _______________________________________________
> _______________________________________________