Неизчерпателен модел във функцията в GHCi

Искам да направя функция, която показва последния елемент от списък. Това е моят код:

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

И получавам следната грешка:

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

Разбрах, че получавате тази грешка, когато липсва случай, но мисля, че съм включил всички възможности. Някакви идеи?


person Diana    schedule 04.11.2014    source източник


Отговори (2)


Ако използвате let във всеки ред, всяка дефиниция ще създаде нова функция с име myLast, засенчвайки всички предишни дефиниции. Така че това, което получавате в крайна сметка, е еквивалентно на

GHCi> нека myLast (x:xs) = myLast xs

сам.

Това, което вероятно искате, е да направите haskell файл, да речем MyLast.hs, съдържащ

module MyLast where

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

след това можете да заредите този файл в GHCi с ghci MyLast.hs.

Ключовата дума let е необходима само когато вече сте в GHCi (или в някоя монада като IO, или в друга функция) и искате да направите локална дефиниция. Но тогава трябва да използвате let само веднъж, напр.

GHCi> let myLast :: [a]->a; myLast [] = грешка; 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

което обаче бих предпочел да напиша като

twiceLast = (2*) . myLast
 where myLast [] = error 
       myLast [x] = x
       myLast (x:xs) = myLast xs
person leftaroundabout    schedule 04.11.2014

В ghci всяко използване на let въвежда нова дефиниция, така че вие ​​предефинирате функцията си няколко пъти, вместо да добавяте случаи.

Две алтернативи:

  • поставете дефиницията във файл и я заредете с командата :r
  • използвайте :{ ... :} за въвеждане на няколко реда:

E.g.:

*Main> :{
*Main| let foo [] = True
*Main|     foo _ = False
*Main| :}
*Main>
person ErikR    schedule 04.11.2014