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

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

最佳答案

Haskell具有三个电力运营商:


(^) :: (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
(^^) :: (Fractional a, Integral b) => a -> b -> a

此运算符允许负整数指数。记住那个x^(-n) == 1/(x^n)。这就是为什么它需要Fractional的原因。

注意,指数必须仍然是整数。 2^^(1%2)不是Fractional数字。
(**) :: Floating a => a -> a -> a

这是“全部捕获”运算符。可以将小数提高到小数幂。但是,这使用浮点数,而不是确切的有理数。


由于我们无法代表所有实数,因此他们决定在需要不精确运算时仅依赖浮点数。

因此,您应该使用类型转换来执行该操作。可能的实现方式可能是:

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


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

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


这将使您可以编写:

27 *^* (2%3)


我使用了两个*来提醒实现中使用的**,并且添加了^来引用前两个运算符的类型...不确定是否有意义,或者也许^**^^*会更好。

但是,最好只使用Double。这实际上取决于数字代表什么以及您对它们的处理方式。

10-06 10:29