Две функции в ^ реализации
Я не понимаю одну вещь о реализации ^
в 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)
1 ответ
Решение
Нет, 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
в последнем. Было бы удивительно найти экземпляр, для которого это имеет смысловой смысл или заметную разницу в производительности, но они, по крайней мере, не одно и то же.