2016-04-10 67 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