GHCi中的非穷举模式

时间:2014-11-04 15:03:15

标签: function haskell multiline read-eval-print-loop 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

我知道你在错过案件时会收到此错误,但我认为我已经包含了所有可能性。有什么想法吗?

2 个答案:

答案 0 :(得分:5)

如果您在每一行中使用let,则每个定义都会生成一个名为myLast new 函数,并隐藏所有先前的定义。所以你最终得到的等同于

  

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 MyLast.hs将该文件加载到GHCi中。

关键字let仅在您已经在GHCi中(或者在某些monad中,如IO或其他函数中)并且想要制作本地定义时才需要。但是你必须只使用let一次,例如

  

GHCI>让myLast :: [a] - > a; myLast [] =错误; myLast [x] = x; myLast(x:xs)= myLast xs

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

答案 1 :(得分:2)

在ghci中,每次使用let都会引入一个新定义,因此您需要多次重新定义函数,而不是添加案例。

两种选择:

  • 将定义放在文件中,并使用:r命令
  • 加载它
  • 使用:{ ... :}输入多行:

E.g:

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