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)
在halfy = round (y/2)
中,你有y :: Int
。但是,(/)
运算符是在 Fractional
typeclass 中定义的(Int
不是它的实例;考虑一下哪个Int
可以表示,例如 3/2
)。
但是,还有整数除法运算符div
和quot
,它们将为您提供四舍五入的Int
结果。因此,只需将halfy
的定义替换为
halfy = y `quot` 2
这将恢复您的halfy
行为,因为暂时忘记打字问题,y/2
的小数部分始终为 0 或 0.5,并且round
将两者四舍五入为 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