2013-01-24 121 views
1

我一直在爲此掙扎半個多小時。我知道這很簡單,但是我對Haskell類型很糟糕,甚至在閱讀了與我的類似問題的可接受答案之後,我仍然無法解決我的問題 - 更別說理解它了!Haskell中的類型問題

代碼:

p108 = [filter (\[a,b] -> a>0 && b>0) (diophantinepairs n) | n <- [1..]] 

diophantinepairs :: Integer -> [[Integer]] 
diophantinepairs n = nub$map sort b 
    where 
     a = divisors n 
     b = [[(n-d), n - (n^2)/d] | d <- a] 

錯誤:

249:39: 
    No instance for (Fractional Integer) 
     arising from a use of `/' 
    Possible fix: add an instance declaration for (Fractional Integer) 
    In the second argument of `(-)', namely `(n^2)/d' 
    In the expression: n - (n^2)/d 
    In the expression: [(n - d), n - (n^2)/d] 

感謝, 薩姆。

回答

8

這裏是你如何閱讀這些樣的錯誤:

No instance for (Fractional Integer) 

翻譯:你的程序有一個Integer,但您使用的就可以了Fractional類的方法之一。

arising from a use of `/' 

翻譯:所涉及的方法是/,這是Fractional類的一部分。 Integer不是Fractional,因此您不能將/應用於整數。

解決方法:改爲使用divquot

我可以得到同樣的錯誤在ghci很輕鬆地:

Prelude> (1 :: Integer)/(2 :: Integer) 

<interactive>:2:16: 
    No instance for (Fractional Integer) 
     arising from a use of `/' 
    Possible fix: add an instance declaration for (Fractional Integer) 
    In the expression: (1 :: Integer)/(2 :: Integer) 
    In an equation for `it': it = (1 :: Integer)/(2 :: Integer) 

備用的解決辦法:使用Fractional類型,如的Rational代替Integer

Prelude> (1 :: Integer) `div` (2 :: Integer) 
0 
Prelude> :m + Data.Ratio 
Prelude Data.Ratio> (1 :: Rational)/(2 :: Rational) 
1 % 2 
+0

覆蓋備選方案的良好答案。在這種特殊情況下,假設除數符合廣告標準,d除以n,所以山姆可以使用div來得到這個整數答案。 – AndrewC

+1

請注意,'div'計算歐幾里得除法的商,'''在數學上有點不太有趣,因爲它只是反映在0左右,但另一方面,在大多數硬件上(「CPU指令」 ),並且考慮到你正在使用自然整數(儘可能多)... – Jedai

+1

@Jedai:對於Integer,它們將是相同的速度,因爲'Integer'分別存儲了符號和大小。至少對於整數大於一個單詞。 –

4

不像某些語言中, /未被重載以在整數上工作。這是有道理的:整數「劃分」與理性劃分不同。在Haskell

(/) :: Fractional a => a -> a -> a 

但正如我所說,Integer不是Fractional這就是爲什麼你會得到

No instance for (Fractional Integer) 

相反,你可以使用quotdiv功能,其執行整數除法。