2014-09-26 41 views
7

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

每当我有这样一个程序:

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

他所做的是,他采取的第一个元素淘汰之列,并与其余部分继续。每当只剩下一个时,xs应该是[],而这又应该触发test [] = []。但是每当我运行这个算法,我得到一个错误。 Exception: <interactive>:20:5-16: Non-exhaustive patterns in function test.

我在网上找不到明确的解释。有人可以给我一个链接,这是明确解释或解释给我?

+1

奇怪。您发布的代码段不包含非穷举模式。 – pyon 2014-09-26 07:22:18

+1

只是在黑暗中拍摄:你可能试图将这个定义输入到ghci中吗?如果是这样,你应该使用一个let语句:'let test [] = [];测试(x:xs)=测试xs'。 – pyon 2014-09-26 07:24:29

+0

是的,这就是我正在做的。非常感谢。我已经开始吓坏了,因为我花了整整一周的时间编程递归,但我无法弄清楚为什么这个工作不起作用。 – 2014-09-26 07:28:46

回答

24

您在问题主体中发布的代码确实是穷尽模式匹配。但是,如果你试图进入这个定义成ghci中,你应该使用一个单一let声明:

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

你在做什么here是不正确。您首先定义一个非详尽的功能test

Prelude> let test [] = [] 

然后你要定义另一非详尽的功能,也称为test,隐藏第一个:

Prelude> let test (x:xs) = test xs 
+1

我希望我可以更多次提升这一点。 – 2016-09-03 23:04:57

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 

请注意我们现在看到我们的功能的程度如何很好!

希望这会有所帮助。干杯!