此代码
(4 :: Integer) / 2
会导致错误:
No instance for (Fractional Integer) arising from a use of ‘/’
In the expression: (4 :: Integer) / 2
In an equation for ‘it’: it = (4 :: Integer) / 2
为什么?
我需要指定
fromIntegral(4 :: Integer) / 2
得到一个结果。但是,如果我需要一个实数而不是2.0
怎么办?
答案 0 :(得分:14)
因为Integer
类型没有Fractional
个实例。
(/)
的类型为Fractional a => a -> a -> a
。考虑a = Integer
时会发生什么。你有Integer -> Integer -> Integer
。但1/2
不是整数,它是0.5
。因此,适合除法运算符的唯一方法是舍入结果。但是不是一种单一的方法,最佳选择取决于应用程序,因此决定不提供该实例。
如果要执行整数除法,请使用div
或quot
函数(它们使用不同的舍入)。
否则转换为支持明确定义的除法操作的东西,如Rational
(这是fromIntegral
正在做的事情。)
答案 1 :(得分:2)
因为整数的除法运算符有两个结果(商和余数):
divMod :: Integer -> Integer -> (Integer, Integer)
您还可以使用div
运算符:
n `div` m
只返回除法结果的一个分量(商),但这与n / m
不同。 /
适用于除法运算符只有一个结果,它将“商”和“余数”组合在一个分数中的类型。
等等,如果(q, r) = n `div` m
,那么
n = m * q + r
而如果q = x / y
,那么
x = y * q
(关于浮点数和近似值的常见警告)。
用div
代替/
打破这种关系,因为它会丢弃重现n
所需的一些信息。
答案 2 :(得分:1)
在Haskell中,类Fractional
包含所有能够分割的类型。实际上,这就是划分的定义;因此,每当Haskell遇到/
时,它会查找正在操作的类型的Fractional
实例。由于Fractional
没有类Integer
的实例,因此Haskell在/
上没有Integer
的定义。
Haskell有几个Num
类的子类,为了以最合适的方式键入类,它们值得熟悉。