overpro
overpro

Reputation: 49

Haskell Recursion ( No instance for (RealFrac Int) arising from a use of ‘round’)

modPow :: Int -> Int -> Int -> Int  
-- Pre: 1 <= m <= sqrt(maxint)  
modPow x y n   
  |even y    = (((x^halfy) `mod` n)^2) `mod` n  
  |otherwise = (x `mod` n)*(x ^ (y-1) `mod` n) `mod` n  
    where halfy = round (y/2)  

REPORT ON TERMINAL:

Recursion.hs:39:19:  
    No instance for (RealFrac Int) arising from a use of ‘round’  
    In the expression: round (y / 2)  
    In an equation for ‘halfy’: halfy = round (y / 2)  
    In an equation for ‘modPow’:  
        modPow x y n  
          | even y = (((x ^ halfy) `mod` n) ^ 2) `mod` n  
          | otherwise = (x `mod` n) * (x ^ (y - 1) `mod` n) `mod` n  
          where  
              halfy = round (y / 2)  

Recursion.hs:39:27:  
    No instance for (Fractional Int) arising from a use of ‘/’  
    In the first argument of ‘round’, namely ‘(y / 2)’  
    In the expression: round (y / 2)  
    In an equation for ‘halfy’: halfy = round (y / 2) 

Upvotes: 1

Views: 1262

Answers (1)

Cactus
Cactus

Reputation: 27636

In halfy = round (y/2), you have y :: Int. However, the (/) operator is defined in the Fractional typeclass (which Int is not an instance of; think about which Int could represent e.g. 3/2).

However, there are also the integer division operators div and quot which will give you rounded, Int results. So just replace that definition of halfy with

halfy = y `quot` 2

This will recover your inteded behaviour of halfy since, forgetting about the typing issues for a moment, the fractional part of y/2 is always going to be either 0 or 0.5, and round rounds both towards 0:

Prelude> round (1/2) :: Int
0
Prelude> round (-1/2) :: Int
0
Prelude> 1 `quot` 2 :: Int
0
Prelude> (-1) `quot` 2 :: Int
0
Prelude> (-1) `div` 2 :: Int -- This doesn't recover the same behaviour for negative y!
-1

Upvotes: 3

Related Questions