Int -> Bool ...">

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 of primeCheck', namely (floor (sqrt n))' In the expression: primeCheck n (floor (sqrt n)) In an equation for isPrime ': 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?

+3
source share
3 answers

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 .

+7
source

The problem is converting from Int to use in sqrt. Change the last line to

 isPrime n = primeCheck n (floor (sqrt (fromIntegral n))) 
+2
source

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:

  • sqrt accepts a Floating argument, and Int not part of a class of type Floating
  • floor requires RealFrac argument, but sqrt only creates Floating

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 .

+2
source

All Articles