2016-10-18 33 views
0

所以我有這個簡單的Haskell功能:簡單哈斯克爾階乘函數不編譯

fact :: (Num a) => a -> a 
fact 0 = 1 
fact n = n * fact (n - 1) 

,當我嘗試用GHCI編譯它,我得到一個錯誤:

test.hs:2:6: error: 
    • Could not deduce (Eq a) arising from the literal ‘0’ 
     from the context: Num a 
     bound by the type signature for: 
        fact :: Num a => a -> a 
     at test.hs:1:1-25 
     Possible fix: 
     add (Eq a) to the context of 
      the type signature for: 
      fact :: Num a => a -> a 
    • In the pattern: 0 
     In an equation for ‘fact’: fact 0 = 1 
Failed, modules loaded: none. 

你看,我知道寫這個函數的更好的方法存在,但我不在乎。我只想讓這個函數編譯。但我不能那樣做。我的印象是,如果某個東西是一個數字,它必定是方程式a的一個實例,因此編譯器提出的可能的修正方案是錯誤的。

我該如何獲得此代碼進行編譯?

+2

使用編譯器的修復建議。 –

回答

1

您假定作爲Num實例的實例的類型也必須是Eq的實例爲false。考慮推斷類型爲你的函數:

> fact 0 = 1; fact n = n * fact (n - 1) 
> :t fact 
fact :: (Num t, Eq t) => t -> t 

要的Num一個實例,一種只需要定義以下功能:

  • (+)
  • (*)
  • abs
  • signum
  • fromInteger
  • 要麼negate(-)
+1

儘管根據Haskell 2010的假設是正確的。 GHC決定在幾個版本之前改變它。 –

+0

有道理;具有「Num」實例的5個「內置」類型「Word」,「Integer」,「Int」,「Float」和「Double」都有一個「Eq」實例,而且我不能真正想到一個你只想要一個'Num'實例的類型的例子。 – chepner

+0

我很想擴展我的答案,但我似乎無法從我的計算機加載haskell.org,並且它似乎是一些模糊的證書過期問題,我現在無法進行調試。 GHC有什麼理由改變它? – chepner