像2^(2%1)
这样的表达式在GHCi中没有进行类型检查,错误消息也很神秘。为什么这不起作用,我需要改变什么?
我无法转换为其他类型,我想要像27^(1%3)
这样的表达式。
答案 0 :(得分:6)
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
可能更好。这实际上取决于数字代表什么以及你在做什么。