Haskell "No instance for" error
I am trying to write a function that checks if a number is prime. I wrote this:
primeCheck :: Int -> Int -> Bool primeCheck ni | n == 2 = True | i == 1 = True | n `mod` i == 0 = False | otherwise = primeCheck n (i -1) isPrime :: Int -> Bool isPrime n = primeCheck n (floor (sqrt n)) And I get the following errors:
There is no instance for (RealFrac Int) resulting from using
floor' Possible fix: add an instance declaration for (RealFrac Int) In the second argument ofprimeCheck', namely(floor (sqrt n))' In the expression: primeCheck n (floor (sqrt n)) In an equation forisPrime ': isPrime n = simpleCheck n (floor (sqrt n))No instance for (Floating Int) arising from a use of `sqrt' Possible fix: add an instance declaration for (Floating Int) In the first argument of `floor', namely `(sqrt n)' In the second argument of `primeCheck', namely `(floor (sqrt n))' In the expression: primeCheck n (floor (sqrt n)) Failed, modules loaded: none.
When I change the code to this, I hope to fix the problem:
primeCheck :: Int -> Int -> Bool primeCheck ni | n == 2 = True | i == 1 = True | n `mod` i == 0 = False | otherwise = primeCheck n (i -1) isPrime :: Int -> Bool isPrime n = primeCheck n (floor (RealFrac (sqrt (Floating n)))) I get this:
Out of scope: RealFrac data constructor
Not in the field: Floating data constructor
How can i fix this?
Floating is a typeclass, not a constructor or function. You seem to understand that you need to convert type n . The correct way to do this is to use fromIntegral :
isPrime n = primeCheck n $ floor $ sqrt $ (fromIntegral n :: Double) We can understand why this works by following the type of function signatures.
From a signature of type isPrime , we see that n is of type Int .
Since sqrt expects some type of Floating (i.e. a type that is an instance of typeclass Floating ), we can convert from Int to Double using fromIntegral . Note that the signature fromIntegral is equal to
(Integral a, Num b) => a -> b Int is an instance of Integral (therefore, the input type is ok), and Double is an instance of Num , so the type of output is ok.
Then take sqrt to get the new Double .
floor expects an argument whose type is an instance of RealFrac . Double is an instance of both Floating and RealFrac , so it will complete the task (without the need for conversion). floor converts the square root back to type Int .
Note that since the output type fromIntegral is polymorphic, like the input type sqrt and floor , we must specify the conversion type as Double , otherwise the compiler will not know which instance of Num / Floating / RealFrac to convert to. You can see the ambiguous type 'a' in ... error.
You can see the signature types of many functions using Hoogle
EDIT
It turns out that an explicit type signature for fromIntegral not required. In this way,
isPrime n = primeCheck n $ floor $ sqrt $ fromIntegral n enough. In my opinion, it would be clearer just to provide an explicit signature, but in this case it is not necessary. You can read about it here .
Floating and RealFrac are class types, not functions.
This page gives a good overview of the Haskell standard hierarchical type hierarchy (section 6.3):
http://www.haskell.org/onlinereport/basic.html
In particular, this class type diagram is very useful:
http://www.haskell.org/onlinereport/classes.gif
You clearly want to take the square root of Int using the sqrt and floor floating point functions. The problem is that these functions have the following types:
sqrt :: Floating a => a -> a floor :: (Integral b, RealFrac a) => a -> b The obstacles are as follows:
sqrtaccepts aFloatingargument, andIntnot part of a class of typeFloatingfloorrequiresRealFracargument, butsqrtonly createsFloating
You can solve the first with the fromIntegral function:
fromIntegral :: (Integral a, Num b) => a -> b which allows you to convert Int (or any other integral type) to any Num type (which includes Floating .)
Further, looking at the diagram of the numerical hierarchy of type classes, we see that Double and Float are members of the classes Floating and RealFrac .
Thus, with the explicit type of enforcement to Double you can apply floor :
isqrt :: Int -> Int isqrt n = floor (sqrt (fromIntegral n) :: Double) Now, as @lthread mentioned, you can get away with:
isqrt :: Int -> Int isqrt n = (floor . sqrt . fromIntegral) n and GHC, by default, returns the sqrt return type in Double . This is great for this, but you should know that this is happening. For example, if you want to use this approach to get the integer square root from Integer , you want to pass the real type of precision abritrary (for example, Data.Number.BigFloat ) instead of Double .