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.

John

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to