Две функции в ^ реализации - PullRequest
       20

Две функции в ^ реализации

0 голосов
/ 27 декабря 2018

Я ничего не понимаю в реализации ^ в 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 Ответ

0 голосов
/ 27 декабря 2018

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

...