2014-11-04 50 views
2

我想创建一个显示列表的最后一个元素的函数。 这是我的代码: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 

我明白,你当你缺少的情况下,这个错误,但我想我已经包括了所有可能性。有任何想法吗?

回答

5

如果在每一行使用let,每个定义将命名为myLast一个功能,阴影之前的所有定义。所以你最终相当于

GHCi> let 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

的关键字时,你已经在GHCI(或者,在一些单子像IO,或在其他功能),并希望做出局部定义只需要let。但是,您只能使用let一次,例如

GHCi> let myLast :: [a]->a; myLast [] = error; 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 
2

在ghci中的let每次使用引入了一个新的定义,让你重新定义你的功能多而不是增加案例。

两种选择:

  • 发生在一个文件中的定义,并与:r命令
  • 使用:{ ... :}加载它进入多行:

例如为:

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