Reading Haskell's Error Messages
Being able to make sense of Haskell’s error messages is an incredibly important skill to have. Here are some error messages you might see and how to interpret them, complete with programs that generate them.
Exception: Nonexhaustive Patterns
Main> main ** Exception: /home/mattox/tmp/noex.hs:5:1-21: Non-exhaustive patterns in function doit
There are two parts to this error message.
/home/mattox/tmp/noex.hs:5:1-21:— This is the file (located in my
noex.hs) where the error occurred. The
5:1-12part means it occurred on line 5, from columns 1 to 21. If you are using a real editor, you can jump directly to that location.
Non-exhaustive patterns in function doitMany of the structures used in Haskell are sum types, a.k.a. disjoint types. This error usually means that a function declaration or expression is missing some of the possible patterns that the type could take.
data Foo = Bar Integer | Baz String deriving Show doit (Bar a) = show a main = do putStrLn (doit (Baz "hi"))
The error was detected on line 5. Notice that
Foo has two constructors,
Baz, but the function
doit is written so that it only handles
doit (Baz "hi") we get the error.
Add a new clause to
doit to handle
Couldn’t match type X with Y
/home/mattox/tmp/noex.hs:5:14: error: • Couldn't match type ‘Foo’ with ‘[Char]’ Expected type: String Actual type: Foo • In the second argument of ‘($)’, namely ‘Foo 10 + 20’ In a stmt of a 'do' block: putStrLn $ Foo 10 + 20 In the expression: do putStrLn $ Foo 10 + 20
On line 5, Haskell thought you were giving it a
String (note that
is a synonym for
String by default), but you gave it a
data Foo = Foo Integer deriving Show main = do putStrLn $ Foo 10 + 20
If you want a
String here, you have to edit the expression to return a
string. You could change the line to
main = do putStrLn $ show (Foo 10 + 20)
but that leads to the next error…
No instance for
(Num XXX) / Where XXX is some type.
/home/mattox/tmp/noex.hs:5:20: error: • No instance for (Num Foo) arising from a use of ‘+’ • In the first argument of ‘show’, namely ‘(Foo 10 + 20)’ In the second argument of ‘($)’, namely ‘show (Foo 10 + 20)’ In a stmt of a 'do' block: putStrLn $ show (Foo 10 + 20) | 5 | putStrLn $ show (Foo 10 + 20) | ^^^^^^^^^^^
This is a weird sounding error; it’s complaining that
is not an instance of
Num. Usually the error is not that you
forgot to make your type an instance of
Num, usually the error is
that you just put the value in a spot where a number was expected.
data Foo = Foo Integer deriving Show main = do putStrLn $ show (Foo 10 + 20)
Normally, you just fix the expression to be
10 + 20. But here’s
what it would look like to make an instance of a type.
data Foo = Foo Integer deriving Show instance Num Foo where Foo x + Foo y = Foo (x + y) Foo x * Foo y = Foo (x * y) negate (Foo x) = Foo (negate x) abs (Foo x) = Foo (abs x) signum (Foo x) = Foo (signum x) fromInteger n = Foo n main = do putStrLn $ show (Foo 10 + 20)
Now when we run this, we get:
*Main> main Foo 30