2014-07-04 24 views
1

我正在使用ghci,並且遇到了用於獲取數字因子的函數的問題。Haskell函數在使用數字時有效,但與變量無關

我想工作的代碼是:

let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0] 

我努力(在這種情況下,與66)來使用它,它不抱怨,當我按下回車鍵,但只要我得到這個錯誤信息:

Ambiguous type variable 't0' in the constraints: 
    (Integral t0) 
    arising from a use of 'factors' at <interactive>:30:1-10 
    (Num t0) arising from the literal '66' at <interactive>:30:12-13 
    (RealFrac t0) 
    arising from a use of 'factors' at <interactive:30:1-10 
    Probable fix: add a type signature that fixes these type variable(s) 
    In the expression: factors 66 
    In the equation for 'it': it = factors 66 

下面的代碼工作完美:

let factorsOfSixtySix = [x | x <- [1..truncate (66/2)], mod 66 x == 0] 

我是新來的Haskell,並查找類型和ty之後佩奇,我還不確定我的意思。

+0

猜猜'n/2'會返回什麼! – devnull

回答

3

使用div整數除法來代替:

let factors n = [x | x <- [1.. n `div` 2], mod n x == 0] 

的問題在你的代碼是/需要RealFrac類型nmod一個Integral之一。在定義時這很好,但是不能選擇適合兩個約束的類型。

另一個選項可能是在使用mod之前截斷n,但更麻煩。畢竟,你不想打電話給factors 6.5,是嗎? ;-)

let factors n = [x | x <- [1..truncate (n/2)], mod (truncate n) x == 0] 
+0

非常感謝,這真的很好。 – Rob

0

如果你把這個頂級綁定(慣用的Haskell)類型註釋,你會得到不同的,可能更多有用的錯誤信息。

GHCi> let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0] 
GHCi> :t factors 
factors :: (Integral t, RealFrac t) => t -> [t] 
GHCi> let { factors :: Double -> [Double]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; } 

<interactive>:30:64: 
    No instance for (Integral Double) arising from a use of `truncate' 
    Possible fix: add an instance declaration for (Integral Double) 
    In the expression: truncate (n/2) 
    In the expression: [1 .. truncate (n/2)] 
    In a stmt of a list comprehension: x <- [1 .. truncate (n/2)] 
GHCi> let { factors :: Integer -> [Integer]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; } 

<interactive>:31:66: 
    No instance for (RealFrac Integer) arising from a use of `truncate' 
    Possible fix: add an instance declaration for (RealFrac Integer) 
    In the expression: truncate (n/2) 
    In the expression: [1 .. truncate (n/2)] 
    In a stmt of a list comprehension: x <- [1 .. truncate (n/2)] 

<interactive>:31:77: 
    No instance for (Fractional Integer) arising from a use of `/' 
    Possible fix: add an instance declaration for (Fractional Integer) 
    In the first argument of `truncate', namely `(n/2)' 
    In the expression: truncate (n/2) 
    In the expression: [1 .. truncate (n/2)] 
0

我是新來的Haskell所以請原諒我的勇氣拿出一個答案在這裏,但最近我已經這樣做了如下;

factors :: Int -> [Int] 
factors n = f' ++ [n `div` x | x <- tail f', x /= exc] 
      where lim = truncate (sqrt (fromIntegral n)) 
        exc = ceiling (sqrt (fromIntegral n)) 
        f' = [x | x <- [1..lim], n `mod` x == 0] 

我相信效率更高。如果你喜歡,你會注意到;

sum (factors 33550336) 
相關問題