The FunctorM library

Thomas Hallgren hallgren at cse.ogi.edu
Mon Mar 21 05:23:40 EST 2005


Simon Marlow wrote:

>On 21 March 2005 01:46, Iavor Diatchki wrote:
>
>>On Mon, 21 Mar 2005 00:29:38 +0100, Thomas Jäger <thjaeger at gmail.com>
>>    
>>
>>>It is already annyoing enough that `Funtor' isn't a subclass of
>>>`Monad' although every monad must also be functor.
>>>      
>>>
Yes it is!

>>I think you are right.  Does anyone remember why "Functor" is not a
>>superclass of "Monad"?
>>    
>>
>I think it is because it doesn't need to be.
>
Superclasses are never really needed, are they? But they are useful 
because they make types smaller and more readable.

For a given type T which has a Monad instance, you can always declare

    instance Functor T where fmap = liftM

so it is not a big burden to have to declare a Functor instance to 
accompany a Monad instance.

And the Haskell libraries already contain superclass relationships that 
make less sense than the Functor=>Monad relationship. For example, why 
is Show and Eq superclasses of Num? Presumably only because it makes 
types more readable. There are types for which you can declare sensible 
instances in the Num class, but not so sensible Show or Eq instances:

    instance Num b => Num (a->b) where
      (f+g) x = f x + g x
      negate f x = negate (f x)
      ...

    instance Num a => Num (IO a) where ...

So, in other words, I think the fact that Functor is not a superclass of 
Monad is a poorly motivated library design inconsistency...

>  The current situation is slightly more flexible: you don't *have* to provide a Functor instance for every Monad instance.  On the other hand, it means you occasionally have to write an additional Functor context in types.  You can always get around that by defining
>
>  class (Functor m, Monad m) => Monad' m where {}
>  
>
Introducing Monad' does not strike me as particularly appealing 
solution, because

   1. For automatically inferred types, it seems pointless, because the
      compiler would presumably still infer types containing "(Functor
      m, Monad m) => ..." rather than "Monad' m => ...".
   2. To be able to use Monad' in explicitly given type signatures, you
      would be forced to declare three instances (Functor, Monad,
      Monad') per type, while if Functor was a superclass of Monad you
      would only need to declare two instances (Functor, Monad).

-- 
Thomas H



More information about the Libraries mailing list