Haskell "No instance for" error

haskell

Solution

`Floating` is a typeclass, not a constructor or function. You do seem to have figured out that you need to convert the type of `n`. The correct way to do this would be using `fromIntegral`:

isPrime n = primeCheck n $ floor $ sqrt $ (fromIntegral n :: Double)

We can see why this works by following the type signatures of the functions.

From the type signature of `isPrime`, we see `n` has type `Int`.

Since `sqrt` expects some `Floating` type (i.e. a type that is an instance of the typeclass `Floating`), we can convert from an `Int` to a `Double` using `fromIntegral`. Note that the signature of `fromIntegral` is

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

`Int` is an instance of `Integral` (so the input type is okay) and `Double` is an instance of `Num` so the output type is okay.

Then we take the `sqrt` to get a new `Double`.

`floor` expects an argument whose type is an instance of `RealFrac`. `Double` happens to be an instance of both `Floating` and `RealFrac`, so it will do the job (no conversion necessary). `floor` will convert the square root back to type `Int`.

Note that since the output type of `fromIntegral` is polymorphic, as is the input type of `sqrt` and `floor`, we have to specify the type of the conversion as `Double`, otherwise the compiler won't know which `Num`/`Floating`/`RealFrac` instance to convert to. You might see the error `ambiguous type 'a' in ...`.

You can see the type signatures of many functions using Hoogle

EDIT

It turns out the explicit type signature for the `fromIntegral` is not required. Thus

isPrime n = primeCheck n $ floor $ sqrt $ fromIntegral n

suffices. In my opinion, it would be clearer to just provide the explicit signature, but it is not necessary in this case. You can read more about it here.

Problem

I am trying to write a function that checks if a number is prime. I wrote this : ``` primeCheck :: Int -> Int -> Bool primeCheck n i | 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 these errors : No instance for (RealFrac Int) arising from a use of `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 = primeCheck 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 to hopefully fix the problem: ``` primeCheck :: Int -> Int -> Bool primeCheck n i | 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 : Not in scope: data constructor `RealFrac' Not in scope: data constructor `Floating' How can I fix this?

Original source

Related problems