In opposition of Functor as super-class of Monad

Petr P petr.mvd at gmail.com
Wed Oct 24 10:01:38 CEST 2012


  Hi,

I was thinking lately about the well known problem that Monad is
neither Functor nor Applicative. As I understand, it is caused by some
historical issues. What I like about Haskell is that it allows to
describe very nicely what different objects actually are - something
that I find very important for programming. And this issue violates
this principle.

This has been discussed here more than year ago in
http://www.haskell.org/pipermail/haskell-prime/2011-January/003312.html
:

On 1/4/11 11:24, oleg at okmij.org wrote:
> I'd like to argue in opposition of making Functor a super-class of
> Monad. I would argue that superclass constraints are not the right
> tool for expressing mathematical relationship such that all monads are
> functors and applicatives.
>
> Then argument is practical. It seems that making Functor a superclass
> of Monad makes defining new monad instances more of a chore, leading
> to code duplication. To me, code duplication is a sign that an
> abstraction is missing or misused.
> ...

The main objections were that it would break existing code and that it
would lead to code duplication. The former is serious, the second can
be easily solved by standard Haskell, since one can define

instance Applicative ... where
    pure   = return
    (<*>)  = ap
instance Functor ... where
    fmap   = liftM

To address the first objection:
AFAIK nobody mentioned the "Default superclass instances" proposal:
http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances
To give an example how it would work:

    class Applicative f => Monad f where
      (>>=) :: f a -> (a -> f b) -> f b
      ...
      instance Applicative f where
        ff <*> fs = ff >>= \ f -> fs >>= \ s -> return (f s)
        ...

This says that if somebody defines an instance of Monad it
automatically becomes an instance of Applicative as defined in the
nested "instance" block. So there is no need to define
Applicative/Functor explicitly, making existing code work.

Implementing this proposal would allow making Monad to extend Functor
and Applicative without breaking existing code. Moreover, this would
simplify other things, for example it would be possible to define an
instance of Traversable and the instances for Functor and Foldable
would be defined implicitly using fmapDefault and foldMapDefault. I'm
sure there are many other cases where splitting type classes into a
more fine-grained hierarchy would be beneficial, and the main reason
against it is simply not to break compatibility with existing code.

IMHO this would be worthwhile to consider for some future revision of Haskell.

  Best regards,
  Petr Pudlak



More information about the Haskell-prime mailing list