2016-04-10 24 views
2

以下是我的阶乘函数:哈斯克尔:什么是错的阶乘函数

factorial :: Integer -> Integer 
factorial n 
    | n < 0 = -1 
    | n > 0 = n * factorial (n-1) 
    | n == 0 = 1 

我猜,我涵盖了所有的情况下(+ VE,-ve,0)。当我尝试加载上面的代码时,我收到以下警告。为什么我会收到警告?

Prelude> :load Fact.hs 
[1 of 1] Compiling Main    (Fact.hs, interpreted) 

Fact.hs:2:1: Warning: 
    Pattern match(es) are non-exhaustive 
In an equation for ‘factorial’: Patterns not matched: _ 
Ok, modules loaded: Main. 

回答

1

我觉得编译器不够聪明,不知道覆盖这三种情况对于特定类型是详尽无遗的。只需在第三条规则中使用otherwise模式而不是零?

(顺便说一句,阶乘通常只为正整数定义的,所以我不知道你的负面分支有多少是正确的。)

4

这是GHC是保守的。您的代码涵盖了所有可能的“n”值,但ghc并不足以证明这一点,所以它会提醒您。

尝试用“其他”替换“n < 0”并将其放在最后。这被定义为

otherwise = True 

这将成为一个全面的情况,这将使ghc舒适。

+0

也就是说,添加的情况下'|否则=错误“不可能发生。”或者沿着这些线路。 – AJFarmar

+0

我认为保罗意味着处理一个合法的案件与一个全面的案件。我会[如果可能,远离'错误'](http://programmers.stackexchange.com/questions/252977/cleanest-way-to-report-errors-in-haskell)。 – zoul

2

编译器无法知道所有输入与三个警卫中的至少一个相匹配。

下面就来解决这个问题,也去除一些重复的建议:

factorial :: Integer -> Integer 
factorial n = case compare n 0 of 
    LT -> -1 
    GT -> n * factorial (n-1) 
    EQ -> 1