问题
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?
回答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
回答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
:rcommand - use
:{ ... :}to enter multiple lines:
E.g.:
*Main> :{
*Main| let foo [] = True
*Main| foo _ = False
*Main| :}
*Main>
来源:https://stackoverflow.com/questions/26738392/non-exhaustive-pattern-in-function-in-ghci