2012-07-31 19 views
1

當我嘗試編譯這段代碼無法推斷出等差數列出現(一個枚舉)`(X - N + 1).. X」

prod [] = 1 
prod (x:xs) = x * prod xs 

ff :: (Num a) => a -> a -> a 
ff x n = prod [(x - n + 1) .. x] 

我獲得以下錯誤:

a.hs:5:15: 
    Could not deduce (Enum a) 
    arising from the arithmetic sequence `(x - n + 1) .. x' 
    from the context (Num a) 
     bound by the type signature for ff :: Num a => a -> a -> a 
     at a.hs:5:1-32 
    Possible fix: 
     add (Enum a) to the context of 
     the type signature for ff :: Num a => a -> a -> a 
    In the first argument of `prod', namely `[(x - n + 1) .. x]' 
    In the expression: prod [(x - n + 1) .. x] 
    In an equation for `ff': ff x n = prod [(x - n + 1) .. x] 

這段代碼有什麼問題?當我用Double代替一切都是正確的。

+1

'Num'不是'Enum',因爲你可以有'Num'類型,很難枚舉,比如'Complex'。 – Landei 2012-07-31 09:58:54

+0

刪除'ff'的類型簽名並查看編譯器推導的類型。 – augustss 2012-07-31 16:31:58

+0

@augustss如何檢查編譯器的推導結果? – Trismegistos 2016-09-19 10:28:40

回答

7

[i .. j]enumFromTo i j的簡寫。 enumFromTo是類型Enum的一部分,而不是Num的一部分(但仍需要Num才能使用+-)。

所以,你需要說a實現Enum以及實施Num

ff :: (Num a, Enum a) => a -> a -> a 
ff x n = prod [(x - n + 1) .. x] 

它與Double因爲Double同時實現了這些類型類。

+0

直指點! – Trismegistos 2012-07-31 10:02:33

1

ff :: (Enum a, Num a) => a -> a -> a
ff x n = prod [(x - n + 1) .. x]

2

爲了[x .. y]工作,結果類型並不需要在所有的一個實例Num(例如,['A'..'Z']作品就好了)。它需要是一個Enum實例。只需將Enum添加到類型簽名即可。

它與Double一起使用,因爲Double有兩個實例。

相關問題