问题
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.
回答1:
The problem is that primes
is a list of Integers (due to your use of mod
), but sqrt
operates on floating-point numbers. If you do x < (ceiling . sqrt . fromIntegral) number
, then it'll work fine. fromIntegral
just converts an integral number into any other numeric type:
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. You could specify another type by changing fromIntegral
to something like (fromIntegral :: Integer -> Float)
.
The reason you don't see this error in GHCi is because your conditional is fine; 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.
来源:https://stackoverflow.com/questions/9114439/instance-declaration-in-haskell