我正在使用ghci而我遇到了一个函数问题,无法获取数字因子。
我想要的代码是:
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的新手,在查找了类型和类型类后,我仍然不确定我的意图。
答案 0 :(得分:3)
使用div
代替整数除法:
let factors n = [x | x <- [1.. n `div` 2], mod n x == 0]
您的代码中的问题是,/
要求RealFrac
n
类型mod
Integral
n
。这在定义期间很好,但是你不能选择适合两种约束的类型。
另一种选择可能是在使用mod
之前截断factors 6.5
,但更麻烦。毕竟,你不想打电话给let factors n = [x | x <- [1..truncate (n/2)], mod (truncate n) x == 0]
,对吗? ; - )
{{1}}
答案 1 :(得分: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)]
答案 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)