views:

575

answers:

5

In the spirit of the other common mistakes in questions, what are the most common mistakes that Haskell programmers make? I've been teaching myself Haskell for a little while and I am starting to feel comfortable enough with the language to start applying it in the real world.

+8  A: 

The most common mistake I know of is introducing a space leak through lazy evaluation. There are lots of ways to achieve this mistake, but one that especially nails programmers with other functional-programming experience is to put a result in an accumulating parameter, thinking that the accumulating parameter will take constant space. In many cases the accumulating parameter takes linear space because parameters are not evaluated.

Another common mistake is to forget that let is always recursive. An unintentional

let x = ... x ...

can lead to baffling outcomes.

Most other common bad experiences manifest not as mistakes but as trouble getting programs past the type checker, or difficulty understanding the monadic I/O model. Difficulties with list comprehensions and with do notations occur occasionally.

In general the difficulties faced by beginning Haskell programmers include

  • Large language with many dark corners, especially in the type system
  • Trouble getting programs to compile, especially when they do I/O
  • Doing everything in the IO monad
  • Great difficulty predicting the time and space behavior of lazy functional programs
Norman Ramsey
+3  A: 

A common mistake for beginning Haskell programmers is to forget the difference between constructor and type namespaces. That was such a beginner's mistake that I'm about embarrassed to have my name attached to it, but I'm pretty confident that others will stumble upon that answer when they have a similar problem, so may as well keep it out there.

Mark Rushakoff
+3  A: 

The difference between [] and [[]]: the empty list and the list with 1 element, namely the empty list. This one especially pops up in base cases of recursive functions.

Martijn
+1  A: 

Use non tail-recursive functions or not strict folds occurring to stack overflow.

Hai
This is less true in Haskell than other functional languages. A lot of the time, laziness makes the non-tail versions of functions a better choice (e.g. you can `foldr` an infinite list, while the tail-recursive `foldl` will explode every time).
Chuck
I know it, but head (x:xs) = head xs + 1 won't explode on a list of 1000000 items?
Hai
A: 

The notion of an expression is quite confusing to beginners. Take the conditional construct in imperative programming languages. There its just a construct but in Haskell its an expression. So an if conditional must have a matching else and both must yield values of the same type of evaluation.

wrongFunc n = if n > 18
              then 1
              else False

The if block evalutes to an integer where as the else returns a bool. This is a common error as in Haskell they are not just block of statements but expressions.

ardsrk
I don't see why that's confusing, and I'm a bit of a Haskell newbie. Compare the same thing in a C-like language: you'd have explicit returns, but the return type would need to be either int or bool and it would be an error to return 1 or false depending on the value of the argument.
Zak