2016-12-01 57 views
1

我试图实现在GHCI递归阶乘的功能,但我收到以下错误:哈斯克尔:在阶乘函数非详尽模式

Prelude> fact n = n * fact (n-1) 
Prelude> fact 0 = 1 
Prelude> fact 1 
*** Exception: <interactive>:2:1-10: Non-exhaustive patterns in function fact 

哪里是从这来了,哪能在将来避免这个错误?

+0

如果您将其写入GHCI之外的文件中,这仍然会发生吗?没有什么突出的我。 – Carcigenicate

+5

这里有一个重复的地方,但基本上你没有提供两个单一的'事实'功能的情况; GHCi 8可以让你从函数定义中删除'let'现在,所以你确实定义了一个为任何参数定义的函数,然后用一个只定义为0的函数替换* – chepner

+3

你可能不会在早期版本中犯这个错误的GHCi;没有'let'的赋值将是一个错误,并且你可能不会误认为'let fact n = ...'后跟'let fact 0 = 1'作为同一个定义的一部分。 – chepner

回答

6

正如人们在评论中指出的那样,GHCi 8的单行定义取代了之前的定义。如果您想输入多模式定义,则需要使用特殊的:{:}代码来开始和结束多行命令。所以,下面的工作正常:

Prelude> :{ 
Prelude| fact 0 = 1 
Prelude| fact n = n * fact (n-1) 
Prelude| :} 
Prelude> fact 10 
3628800 
Prelude> 

(请注意,这是适用于GHCI 8只,而不是7)

此外,介意你定义的顺序。在Haskell,图案事项顺序,因此,如果您尝试匹配fact n第一,它会一直匹配,因此您的fact 0格局将永远不会被使用..

编辑:对于GHCI 7,您需要使用let与语法输入多模式定义的适当缩进:

Prelude> :{ 
Prelude| let fact 0 = 1 
Prelude|  fact n = n * fact (n-1) 
Prelude| :} 
Prelude> fact 10 
3628800 
Prelude> 
+0

多行语法是相同的。改进之处在于定义不再需要'let',这对于多行定义尤其令人讨厌。 – dfeuer