Non exhaustive pattern in function in GHCi

I want to make a function that displays the last element of a list. This is my code:

ghci> let myLast :: [a] -> a
ghci> let myLast [] = error 
ghci> let myLast [x] = x
ghci> let myLast (x:xs) = myLast xs

And I get the following error:

***Exception: Non-exhaustive patterns in function myLast

I understood that you get this error when you're missing a case, but I think I have included all the possibilities. Any ideas?


Solution 1:

If you use a let in each line, each definition will make a new function named myLast, shadowing all the previous definitions. So what you end up with is equivalent to

GHCi> let myLast (x:xs) = myLast xs

alone.

What you probably want is to make a haskell file, say MyLast.hs, containing

module MyLast where

myLast :: [a] -> a
myLast [] = error 
myLast [x] = x
myLast (x:xs) = myLast xs

you can then load that file into GHCi with ghci MyLast.hs.

The keyword let is only needed when you're already in GHCi (or, in some monad like IO, or in another function) and want to make a local definition. But then you must only use the let once, e.g.

GHCi> let myLast :: [a]->a; myLast [] = error; myLast [x] = x; myLast (x:xs) = myLast xs

or

twiceLast :: [Int] -> [Int]
twiceLast = let myLast [] = error 
                myLast [x] = x
                myLast (x:xs) = myLast xs
            in \xs -> 2 * last xs

which I would, however, prefer to write as

twiceLast = (2*) . myLast
 where myLast [] = error 
       myLast [x] = x
       myLast (x:xs) = myLast xs

Solution 2:

In ghci each use of let introduces a new definition, so you are redefining your function multiple times instead of adding cases.

Two alternatives:

  • place the definition in a file and load it with the :r command
  • use :{ ... :} to enter multiple lines:

E.g.:

*Main> :{
*Main| let foo [] = True
*Main|     foo _ = False
*Main| :}
*Main>