^实现中的两个功能

时间:2018-12-27 02:55:15

标签: haskell haskell-prelude

我对^中的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]

我们为什么需要ff 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 :(得分:3)

否,f x y不仅是g x y 1g x 3 1呼叫g (x*x) 1 (x*1),而且f x 3呼叫g (x*x) 1 x。特别是,最后一个参数在前者中为x*1,在后者中为x。令人惊讶的是,找到一个实例,它对此造成语义差异或明显的性能差异,但至少它们不是完全相同的。