[Haskell-cafe] Why do I have to specify (Monad m) here again?

Sebastian Sylvan sebastian.sylvan at gmail.com
Sun Feb 18 14:17:55 EST 2007

On 2/18/07, David Tolpin <david.tolpin at gmail.com> wrote:
> > I think you, and probably Marc Weber as well, are confusing what a
> > constraint on a class head means. Suppose you have:
> >
> > class Monad m => Foo m
> >
> > That constraint means that every instance of class Foo must also be an
> > instance of class Monad. So, as I explained in my email to Marc, we
> > must use:
> >
> > instance Monad m => Foo m
> >
> > And not:
> >
> > instance Foo m
> >
> > Because, in general, m isn't an instance of Monad.
> Hi David,
> Why the compiler cannot infer  class constraint on m from class definition in instance definition while it can in function type definition?

But it can't! If you give a type to a function, it will assume zero
class constraints unless you specify them (just like it will when you
give a type to an instance declaration). If you do something like:

foo :: [a] -> a
foo  = head . sort

It will *not* compile. "sort" requires "Ord", but that does *not* mean
that you can write a type declaration with just a type variable and
have it automatically infer that you need an "Ord" constraint and add
it for you (in fact, that's a good thing, it will tell you that you
forgot an Ord constraint, which may be symptomatic of some other

If you write down a type explicitly, Haskell will not change it for
you into something else just to make the program compile. It *could*
infer that the type for "foo" above needs to have an Ord constraint
and just add it, but if it did then the whole point of type checking
would be disappear. You *want* an error when types don't match!
With functions you can leave out the type and Haskell will infer a
type (which will have the correct constraints), but we don't have the
option of leaving out the types when declaring instances. Haskell
doesn't have any "instance inference" (and I'm not sure what that
would even mean), you have to give the type of your instance
explicitly, and when doing so you are not allowed to skip parts of the
type because they are required elsewhere. Again, just like with
functions, Haskell will not change your supplied type into something
else if there is a mismatch, it will give you an error instead (which
is what you want).

Sebastian Sylvan
UIN: 44640862

More information about the Haskell-Cafe mailing list