Indeed. I spent a year working rather intensively on both ML and Haskell (which are structurally similar but have some crucial differences) and one of the first things I learned is that while it's tempting to implement a factorial like this:
fact 0 = 1
fact 1 = 1
fact n | n < 0 = error "Negative factorial!"
| otherwise = n * fact (n - 1)
your life will be vastly improved if you implement it like this:
fact 0 = 1
fact 1 = 1
fact n | n < 0 = error "Negative factorial!"
| otherwise = g 1 n where
g x 1 = x
g x n' = g (x * n') (n' - 1)
because the latter uses tail recursion and the former doesn't. |