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

Marc Weber marco-oweber at gmx.de
Mon Feb 19 17:59:14 EST 2007

Hi David.

I see that its useful to add complete type signatures without letting
the compiler add stuff magically. This is why I've tried to write the final
question down under a new topic wether it would be useful to be able to write
down partial type signatures where browsing coders know that they are not
complete... (Scroll down to see my answer)
When introducing a new concept ( partially typed functions ) we don't have to discuss
wether type signatures are useful.

I will indicate this incomplete type signature by adding [...] at the end.

> type we wrote down. Imagine that print is in a library and a user's
> browsing the source of this library. They see the print function and
> try to use it on something that doesn't satisfy the Show constraint.
> The compiler bombs out with 'Cannot find Show instance' and the user
> is confused. 
Every haskell newbe will be confused by any error message ;)
But the haskell programmer will only be confused the first time *lol*
Then he knows how to handle it.

> print :: Show a => a -> IO ()
> print x = show x
> If we hadn't written that type signature, then the compiler would
> infer a type and accept the program. 
Aeh. Was this really the issue talking about wether its useful to write down
type signatures or writing down incomplete signatures users not knowing them
beeing incomplete?
Talking about:
	print x :: a -> IO () [...]
	print x = show x
the compiler would not have compiled this in any case.

However, as we _did_ provide a
> type signature, it acts a little like a spec or QuickCheck property
> and reveals a typo straight away: we missed out the putStrLn.
> Similarly, if we write the type:

> print :: a -> IO ()
> Then the attitude taken by the language designers dictates that that's
> what you mean. If you then try to use show, you presumably made a
> mistake writing the type. The compiler could correct this mistake, but
> would we want it to? Perhaps this small error is indicative of a
> larger conceptual error we made; perhaps our spec says that print
> should indeed have the type we wrote, and the mistake was in using
> show.
> So we've determined that if we provide explicit types for functions,
> these should match up with the type the compiler infers. Instances are
> just the same. 
They are not. Why? As I have look at the class declaration as well when looking
at instances ..
Expressed differently:
  function implementation <-> function type signature
corresponds to 
  class method implementation <-> class type signature (1) (Monad m => ...)
  class method implementation <-> instance type signature (2) (Monad m => has to be repeated here)

When looking at types (when browsing instances (2)) I'm always looking at the class
type declaration (1) as well. So in my given example class (Monad m) => ... I would
have seen it anyway.

I could only think of one example where omitting the (Monad m) => part might be useful:
You have a class providing a function 
match regex subject = ...
and two implementations returning (before, match, after) or (match)

Then you might want to write
show3 :: (a,a,a)
show3 = show
te use show3 to select the right implementation.

But in this case it is more convinient to write
show3 a@(_,_,_) = show a

So I'm totally convinced that we don't need new language features..


More information about the Haskell-Cafe mailing list