【问题标题】:Raising a RealFrac to another RealFrac power将 RealFrac 提升到另一个 RealFrac 幂
【发布时间】:2015-10-24 04:20:05
【问题描述】:

我正在尝试将 RealFrac 类型的数字提升到另一个数字的幂,同样是 RealFrac 类型。 This question on exponentiation 有助于解释 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

【问题讨论】:

    标签: haskell types exponentiation


    【解决方案1】:

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

    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 类型)传递给它,精确分数的额外精度将会丢失,因为(**) 是一个浮点运算。

    【讨论】:

    • 啊,是的,对不起,我的意思是**。这很好用,谢谢 - 我花了一些时间来适应 haskells 类型系统。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    相关资源
    最近更新 更多