[Haskell-cafe] Why is $ right associative instead
rjmh at cs.chalmers.se
Mon Feb 6 02:39:59 EST 2006
Cale Gibbard wrote:
>That said, I'd *really* like to see monad comprehensions come back,
>since they align better with the view that monads are container types,
>dual to the view that monads are computations, which is supported by
>the do-syntax. This view is actually much easier to teach (in my
>experience). Giving lists a little extra syntax is nice, but giving
>things unnecessarily restrictive types seems to be the point at which
>I'd consider it going too far.
The trouble with monad comprehensions was that it became far too easy to
write ambiguous programs, even when you thought you were just working
with lists. Haskell overloading works really nicely *as long as there's
a judicious mixture of overloaded and non-overloaded functions*, so that
the overloading actually gets resolved somewhere. Overload too many
things, and you end up having to insert type annotations in the middle
of expressions instead, which really isn't nice.
Lists are special, not least because they come very early in a Haskell
course--or, in my case, in the first ever programming course my students
have ever taken. Getting error messages about ambiguous overloading when
they are still trying to understand what comprehension notation means
(without even the concept of a for-loop to relate it to) is very
destructive. And this is in the case where the code is otherwise
type-correct--the kind of error message you would get by trying to
append a number to a monad comprehension doesn't bear thinking about!
The class system is already something of an obstacle in teaching,
because you have to mention it in the context of arithmetic (even if you
tell students always to write monomorphic type signatures, they still
see classes mentioned in error messages). After all, that is surely why
Helium doesn't have it. I find classes manageable for arithmetic, even
if students do take some time to learn to distinguish between a class
and a type (or a type and a value, for that matter!). But it's a relief
that list programs, at least, have simple non-overloaded types. List
functions provide an opportunity to introduce polymorphism in a simple
context--it's much easier to understand why (++) should have the type
[a] -> [a] -> [a], than to start talking about MonadPlus m => m a -> m a
-> m a.
There is a lot to learn in Haskell, especially in the type and class
system. It's an advantage if you don't have to learn it all at once--if
you can master lists and list comprehensions without exposure to monads
(which are a much harder concept). We should never forget that beginners
have somewhat different needs from expert programmers--and those needs
are also important. If we want Haskell to be used for first programming
courses (and it's a big advantage to catch 'em early), then there needs
to be a learning path into the language that goes quite gently.
Monomorphic lists help with that.
We did consider more aggressive defaulting to address the ambiguity
problems with monad comprehensions--defaulting Monad to lists, for
example, or user-declared defaulting rules--but this introduces yet more
complexity without really addressing the problem of keeping types simple
for beginners, so the idea was abandoned.
More information about the Haskell-Cafe