简体   繁体   English

Haskell中的实例声明

[英]Instance declaration in Haskell

I have these two functions: 我有这两个功能:

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]

The thing is that when I'm trying to load module which contains those functions, I see following error message: 问题是,当我尝试加载包含这些函数的模块时,我看到以下错误消息:

[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'

I really can't understand what's the problem, because when I'm trying to make a small function from piece of code, which, as far as I understand, cause these errors, right in ghci, like let f number x = x < (ceiling . sqrt) number I don't see any error messages. 我真的无法理解是什么问题,因为当我试图从一段代码中创建一个小函数时,据我所知,这会导致这些错误,就在ghci中,就像让f number x = x < (ceiling.sqrt)数字我没有看到任何错误消息。

The problem is that primes is a list of Integers (due to your use of mod ), but sqrt operates on floating-point numbers. 问题是primes是一个Integers列表(由于你使用了mod ),但是sqrt是在浮点数上运行的。 If you do x < (ceiling . sqrt . fromIntegral) number , then it'll work fine. 如果你做x < (ceiling . sqrt . fromIntegral) number ,那么它将正常工作。 fromIntegral just converts an integral number into any other numeric type: fromIntegral只是将整数转换为任何其他数字类型:

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

In this case, since you don't specify any specific floating-point type to convert to, it'll default to using Double values to compute the square root. 在这种情况下,由于您没有指定要转换的任何特定浮点类型,因此默认使用Double值来计算平方根。 You could specify another type by changing fromIntegral to something like (fromIntegral :: Integer -> Float) . 您可以通过将fromIntegral更改为类似(fromIntegral :: Integer -> Float)来指定其他类型。

The reason you don't see this error in GHCi is because your conditional is fine; 您在GHCi中没有看到此错误的原因是因为您的条件很好; it just works on different types to the ones you're using here. 它只适用于你在这里使用的不同类型。 Just verifying that a piece of code is correct in isolation isn't enough; 仅仅验证一段代码在隔离中是否正确是不够的; for it to pass the type checker, it has to make sense in context too. 为了通过类型检查器,它也必须在上下文中有意义。

You might want to consider using an integer square root algorithm for accuracy. 您可能需要考虑使用整数平方根算法来提高准确性。

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

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