繁体   English   中英

Haskell中的实例声明

[英]Instance declaration in Haskell

我有这两个功能:

primes = sieve [2..] 
    where
        sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
isPrime number = number /= 1 && null [x | x <- takeWhile (\x -> x < (ceiling . sqrt) number) primes, mod number x == 0]

问题是,当我尝试加载包含这些函数的模块时,我看到以下错误消息:

[2 of 2] Compiling Main             ( euler37.hs, interpreted )

euler37.hs:6:70:
No instance for (RealFrac Int)
  arising from a use of `ceiling'
Possible fix: add an instance declaration for (RealFrac Int)
In the first argument of `(.)', namely `ceiling'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

euler37.hs:6:80:
No instance for (Floating Int)
  arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the second argument of `(.)', namely `sqrt'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

我真的无法理解是什么问题,因为当我试图从一段代码中创建一个小函数时,据我所知,这会导致这些错误,就在ghci中,就像让f number x = x < (ceiling.sqrt)数字我没有看到任何错误消息。

问题是primes是一个Integers列表(由于你使用了mod ),但是sqrt是在浮点数上运行的。 如果你做x < (ceiling . sqrt . fromIntegral) number ,那么它将正常工作。 fromIntegral只是将整数转换为任何其他数字类型:

fromIntegral :: (Integral a, Num b) => a -> b

在这种情况下,由于您没有指定要转换的任何特定浮点类型,因此默认使用Double值来计算平方根。 您可以通过将fromIntegral更改为类似(fromIntegral :: Integer -> Float)来指定其他类型。

您在GHCi中没有看到此错误的原因是因为您的条件很好; 它只适用于你在这里使用的不同类型。 仅仅验证一段代码在隔离中是否正确是不够的; 为了通过类型检查器,它也必须在上下文中有意义。

您可能需要考虑使用整数平方根算法来提高准确性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM