将浮点数舍入到haskell中的int

时间:2015-01-20 09:10:28

标签: haskell casting type-conversion

Euler项目的问题3:13195的主要因素是5,7,13和29。 600851475143的最大主要因素是什么?

我做了一个懒惰的素数列表,然后我做了一个takeWhile它们小于600851475143的平方根,并测试每个素数以查看它是否是一个因素。

primes :: [Integer]
primes = sieve [2..]
    where
        sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
primeFactors :: Integer -> Integer
primeFactors x = last $ filter (\y -> x `mod` y == 0) $ takeWhile (< floor (sqrt x)) $ primes

但是,(< floor (sqrt x))

出错了
projecteuler.hs:34:70:
    No instance for (RealFrac Integer) arising from a use of `floor'
    Possible fix: add an instance declaration for (RealFrac Integer)
    In the second argument of `(<)', namely `floor (sqrt x)'
    In the first argument of `takeWhile', namely `(< floor (sqrt x))'
    In the expression: takeWhile (< floor (sqrt x))

projecteuler.hs:34:77:
    No instance for (Floating Integer) arising from a use of `sqrt'
    Possible fix: add an instance declaration for (Floating Integer)
    In the first argument of `floor', namely `(sqrt x)'
    In the second argument of `(<)', namely `floor (sqrt x)'
    In the first argument of `takeWhile', namely `(< floor (sqrt x))'

这很奇怪:: t floor给了我(Integral b, RealFrac a) => a -> b,这意味着这个楼层应该返回一个整数。如何添加实例声明(或执行必要的操作来解决此问题?)

此外,我们非常感谢有关代码优化的任何建议:)

编辑:这已经解决了,现在我正在清理它。我已经将所有内容封装在main函数中,所以看起来像这样:

p003primeFactors :: Integer -> [Integer]
p003primeFactors x = filter (\y -> x `mod` y == 0) $ takeWhile (\p -> p^2 <= x) $ primes
    where
        primes :: [Integer]
        primes = sieve [2..]
            where
                sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]

这是为这样的函数创建名称空间的最佳方法吗?

1 个答案:

答案 0 :(得分:3)

实际问题是第二个错误。 (第一个只是结果。)xInteger,因此您无法在其上调用sqrt,因为这需要Floating个实例。

尝试:

takeWhile (< floor (sqrt (fromIntegral x)))

这会将x从整数转换为浮点数,以便sqrt可以对其进行操作。