Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instance declaration in Haskell

Tags:

haskell

ghci

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.

like image 445
aga Avatar asked Jan 31 '26 22:01

aga


1 Answers

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.

like image 73
ehird Avatar answered Feb 02 '26 14:02

ehird



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!