【问题标题】:Non exhaustive pattern in function in GHCiGHCi 中的非详尽功能模式
【发布时间】:2019-01-25 11:34:37
【问题描述】:
我想创建一个显示列表最后一个元素的函数。
这是我的代码:
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
我知道您在遗漏案例时会收到此错误,但我想我已经包含了所有可能性。有什么想法吗?
【问题讨论】:
标签:
function
haskell
multiline
read-eval-print-loop
ghci
【解决方案1】:
如果您在每一行中使用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 MyLast.hs 将该文件加载到 GHCi。
关键字let 仅在您已经在GHCi 中(或者,在像IO 这样的monad 中,或在另一个函数中)并且想要进行本地定义 时才需要。但是你必须只使用一次let,例如
GHCi> let myLast :: [a]->a; 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>