Patrón no exhaustivo en función en GHCi

Quiero hacer una función que muestre el último elemento de una lista. Este es mi código:

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

Y obtengo el siguiente error:

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

Entendí que obtienes este error cuando te falta un caso, pero creo que he incluido todas las posibilidades. ¿Algunas ideas?

Si usa un let en cada línea, cada definición creará una nueva función llamada myLast , que sombreará todas las definiciones anteriores. Entonces, ¿con qué terminas es equivalente a

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

solo.

Lo que probablemente quiera es crear un archivo MyLast.hs , digamos MyLast.hs , que contenga

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

a continuación, puede cargar ese archivo en GHCi con ghci MyLast.hs .

La palabra clave let solo se necesita cuando ya está en GHCi (o, en alguna mónada como IO , o en otra función) y quiere hacer una definición local . Pero solo debes usar el let una vez, por ejemplo

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

o

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

que, sin embargo, preferiría escribir como

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

En ghci cada uso de let introduce una nueva definición, por lo que está redefiniendo su función varias veces en lugar de agregar casos.

Dos alternativas:

  • coloque la definición en un archivo y cárguelo con el comando :r
  • use :{ ... :} para ingresar varias líneas:

P.ej:

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