将RealFrac提升到另一个RealFrac电源

时间:2015-08-01 16:46:34

标签: haskell types exponentiation

我正在尝试将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

1 个答案:

答案 0 :(得分:2)

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

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。如果您真的需要使用(**) RealFrac合作的功能,则需要使用realToFrac转换值:

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

当然,如果你定义splitFunc r l = realToFrac r ** realToFrac l并向其传递精确分数(例如类型为Ratio Integer的东西),精确分数的额外精度将会丢失,因为(**)是浮动的点操作。