Haskell递归(使用'round'时没有(RealFrac Int)的实例)

时间:2014-12-29 01:20:09

标签: haskell recursion

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)  

终端报告:

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) 

1 个答案:

答案 0 :(得分:2)

halfy = round (y/2),您有y :: Int。但是,(/)类型操作符(Fractional类型中定义了Int运算符(Int不是实例;请考虑3/2可以表示哪个Int)。

但是,integer division operators div and quot还会为您提供四舍五入的halfy结果。所以只需用{/ 1>替换halfy = y `quot` 2 的定义即可

halfy

这将恢复您y/2的有意行为,因为暂时忘记了输入问题,round的小数部分始终为0或0.5,{{1}向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