我对^
中的haskell
的实现一无所知:
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
我们为什么需要f
? f x y
只是g x y 1
吗?
是某种优化还是缺少一些东西?
如果我以以下方式更改代码,它将起作用吗?
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = g x0 y0 1
where
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z)
答案 0 :(得分:3)
否,f x y
不仅是g x y 1
:g x 3 1
呼叫g (x*x) 1 (x*1)
,而且f x 3
呼叫g (x*x) 1 x
。特别是,最后一个参数在前者中为x*1
,在后者中为x
。令人惊讶的是,找到一个实例,它对此造成语义差异或明显的性能差异,但至少它们不是完全相同的。