为什么不能在Haskell中划分整数?

时间:2016-03-11 21:51:49

标签: haskell

此代码

(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怎么办?

3 个答案:

答案 0 :(得分:14)

因为Integer类型没有Fractional个实例。

(/)的类型为Fractional a => a -> a -> a。考虑a = Integer时会发生什么。你有Integer -> Integer -> Integer。但1/2 不是整数,它是0.5。因此,适合除法运算符的唯一方法是舍入结果。但是是一种单一的方法,最佳选择取决于应用程序,因此决定提供该实例。

如果要执行整数除法,请使用divquot函数(它们使用不同的舍入)。 否则转换为支持明确定义的除法操作的东西,如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类的子类,为了以最合适的方式键入类,它们值得熟悉。