代码之家  ›  专栏  ›  技术社区  ›  BenJacob Petr

将RealFrac提升到另一个RealFrac级别

  •  1
  • BenJacob Petr  · 技术社区  · 9 年前

    我试图提出一个类型为的数字 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 回复  |  直到 7 年前
        1
  •  2
  •   duplode    9 年前

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

    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 )对它来说,精确分数的额外精度将丢失,因为 (**) 是浮点运算。