将数字提高到小数(Data.Ratio)?

时间:2015-08-24 06:12:44

标签: haskell types ghci exponentiation

2^(2%1)这样的表达式在GHCi中没有进行类型检查,错误消息也很神秘。为什么这不起作用,我需要改变什么?

我无法转换为其他类型,我想要像27^(1%3)这样的表达式。

1 个答案:

答案 0 :(得分:6)

Haskell有三个电源运算符:

  1. (^) :: (Num a, Integral b) => a -> b -> a

    使用正整数指数提升任何类型的数字。

    在输入Could not deduce (Integral (Ratio a0)) arising from a use of ‘^’时,您收到2^(2%3)这样的错误,因为Data.Ratio 不是 Integral的实例。 GHC认为^想要Integral,而通知Data.Ratio不能在这种情况下使用。

  2. (^^) :: (Fractional a, Integral b) => a -> b -> a

    此运算符允许负积分指数。请记住x^(-n) == 1/(x^n)。这就是为什么它需要Fractional

    请注意,指数必须仍然是整数。 2^^(1%2) Fractional号码。

  3. (**) :: Floating a => a -> a -> a

    这是“全部捕获”操作符。它可以将分数提升到分数幂。然而,这使用浮点数,而不是精确的有理数。

  4. 由于我们不能代表所有实数,所以当你想要不精确的操作时,他们决定简单地依赖浮点数。

    因此应该使用类型转换来执行该操作。 可能的实施可能是:

    realToFrac $ 27**(realToFrac $ 2%3) :: Rational
    

    或者您可以定义一个新的运算符:

    (*^*) :: (RealFrac a, RealFrac b) => a -> b -> a
    x *^* y = realToFrac $ realToFrac x ** realToFrac y
    

    这将允许你写:

    27 *^* (2%3)
    

    我使用了两个*来提醒实现中使用的**,我添加了一个^来引用前两个运算符的类型......不确定这是否合理,或者^**^^*可能会更好。

    然而,简单地使用Double可能更好。这实际上取决于数字代表什么以及你在做什么。