GHCi 中的非详尽功能模式

Posted

技术标签:

【中文标题】GHCi 中的非详尽功能模式【英文标题】:Non exhaustive pattern in function in GHCi 【发布时间】:2014-12-31 12:50:07 【问题描述】:

我想创建一个显示列表最后一个元素的函数。 这是我的代码:

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

我知道您在遗漏案例时会收到此错误,但我想我已经包含了所有可能性。有什么想法吗?

【问题讨论】:

【参考方案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> 让 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>

【讨论】:

以上是关于GHCi 中的非详尽功能模式的主要内容,如果未能解决你的问题,请参考以下文章

GHCi中的“return 1”如何显示“1”? [复制]

GHCi“让”——它有啥作用?

在 shell 脚本中编写 ghci 会话

在哪里清理处置模式中的非托管资源?

text 如何从Git中的非分段更改中删除说“旧模式100755新模式100644”的文件?

如何读取 ghci 类型错误?