11

我正在为明天的测试进行培训,以完成对函数式编程的介绍,但有一件事我不明白。

每当我有这样的程序时:

test [] = []
test (x:xs) = test (xs)

他所做的是从列表中取出第一个元素并继续其余的。每当只剩下一个时,xs应该[]依次触发test [] = []。但是每当我运行这个算法时,我都会得到一个错误。Exception: <interactive>:20:5-16: Non-exhaustive patterns in function test.

我在网上找不到明确的解释。有人可以给我一个链接,其中解释清楚或向我解释吗?

4

2 回答 2

30

您在问题正文发布的代码进行了详尽的模式匹配。但是,如果您尝试将此定义输入 ghci,则应使用单个 let语句:

Prelude> let test [] = [] ; test (x:xs) = test xs

你在这里做的是不正确的。您首先定义一个非详尽的函数test

Prelude> let test [] = []

然后你正在定义另一个非穷举函数,也称为test,它隐藏了第一个函数:

Prelude> let test (x:xs) = test xs
于 2014-09-26T07:31:39.917 回答
4

在 Haskell 的 REPL (GHCi) 中尝试婴儿程序确实是一件非常棘手的事情。

使用let不是很明显(特别是,因为在单独的“脚本/程序”中不需要它)。

有时我们不想创建一个完整的文件,而是尝试一个带有不同“案例”的小函数。

另一种有用的方法是使用分隔符:{&:}来定义我们的功能范围。

假设我们想尝试一个简单的递归sum函数,它可以添加一个数字列表。然后我们会说以下内容:

λ > :{
Prelude| sum [] = 0
Prelude| sum (x:xs) = x + sum xs
Prelude| :}
sum :: Num t => [t] -> t
Prelude
λ > sum [1..10]
55
it :: (Enum t, Num t) => t

请注意,我们现在可以很好地看到我们的功能范围!

希望这可以帮助。干杯!

于 2017-06-11T17:15:21.370 回答