Неисчерпывающий шаблон функций в 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 [] = ошибка; мой последний [х] = х; мояПоследняя (x:xs) = мояПоследняя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