将 RealFrac 提高到另一个 RealFrac 幂

Raising a RealFrac to another RealFrac power

我正在尝试对一个类型为 RealFrac 的数字求另一个类型为 RealFrac 的数字的幂。 This question 关于求幂有助于解释 Haskell 中的各种求幂函数,我相信我需要使用 (^) 来保留任何非整数值。但是我该如何处理这些类型呢?我不断遇到这样的错误:

Could not deduce (Integral a) arising from a use of ‘^’
from the context (RealFrac a)
  bound by the type signature for
             splitFunc :: RealFrac a => a -> a -> a
  at Procedural/City.hs:41:16-42
Possible fix:
  add (Integral a) to the context of
    the type signature for splitFunc :: RealFrac a => a -> a -> a
In the expression: r ^ l
In an equation for ‘splitFunc’: splitFunc r l = r ^ l

两个问题。首先,您不需要 (^),而是 (^^)(如果您的指数始终是整数)或 (**)(如果您需要浮动指数):

Prelude> :t (^)
(^) :: (Integral b, Num a) => a -> b -> a
Prelude> :t (^^)
(^^) :: (Fractional a, Integral b) => a -> b -> a
Prelude> :t (**)
(**) :: Floating a => a -> a -> a

其次,RealFrac不仅包括浮点数,还包括,例如,exact fractions. If you really need your function to use (**) and work with any RealFrac you will need to convert the values with realToFrac:

Prelude> :t realToFrac 
realToFrac :: (Fractional b, Real a) => a -> b

当然,如果您定义 splitFunc r l = realToFrac r ** realToFrac l 并将精确分数(例如 Ratio Integer 类型的东西)传递给它,精确分数的额外精度将会丢失,因为 (**) 是浮点运算。