^ 实现中的两个函数
Two function in ^ implementation
关于 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)
不,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
。找到一个实例会产生语义上的差异或明显的性能差异,这将是令人惊讶的,但它们至少不是完全相同的东西。
关于 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)
不,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
。找到一个实例会产生语义上的差异或明显的性能差异,这将是令人惊讶的,但它们至少不是完全相同的东西。