Haskell CS 421 LogoCS 421 — Programming Languages

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

The Error

 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 tmp directory, called noex.hs) where the error occurred. The 5:1-12 part 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 doit Many 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.

The Program

data Foo = Bar Integer
         | Baz String
  deriving Show

doit (Bar a) = show a
main = do
  putStrLn (doit (Baz "hi"))

Interpretation

The error was detected on line 5. Notice that Foo has two constructors, Bar and Baz, but the function doit is written so that it only handles Bar. When main calls doit (Baz "hi") we get the error.

The Fix

Add a new clause to doit to handle Baz.

Couldn’t match type X with Y

The Error

/home/mattox/tmp/noex.hs:5:14: error:Couldn't match typeFoowith[Char]Expected type: String
        Actual type: FooIn the second argument of($), namelyFoo 10 + 20In a stmt of a 'do' block: putStrLn $ Foo 10 + 20
      In the expression: do putStrLn $ Foo 10 + 20

Interpretation

On line 5, Haskell thought you were giving it a String (note that [Char] is a synonym for String by default), but you gave it a Foo.

The Program

data Foo = Foo Integer
  deriving Show

main = do
  putStrLn $ Foo 10 + 20

The Fix

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.

The Error

/home/mattox/tmp/noex.hs:5:20: error:No instance for (Num Foo) arising from a use of+’
    • In the first argument ofshow, namely(Foo 10 + 20)In the second argument of($), namelyshow (Foo 10 + 20)In a stmt of a 'do' block: putStrLn $ show (Foo 10 + 20)
  |
5 |   putStrLn $ show (Foo 10 + 20)
  |                    ^^^^^^^^^^^

Interpretation

This is a weird sounding error; it’s complaining that Foo 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.

The Program

data Foo = Foo Integer
  deriving Show

main = do
  putStrLn $ show (Foo 10 + 20)

The Fix

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