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

bar*_*ara 9 haskell

这段代码

(4 :: Integer) / 2
Run Code Online (Sandbox Code Playgroud)

会导致错误:

  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
Run Code Online (Sandbox Code Playgroud)

为什么?

我需要指明

fromIntegral(4 :: Integer) / 2
Run Code Online (Sandbox Code Playgroud)

得到一个结果.但是如果我需要一个实数而不是2.0呢?

Bak*_*riu 18

因为Integer类型没有Fractional实例.

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

如果要执行整数除法,请使用divquot函数(它们使用不同的舍入).否则转换为支持明确定义的除法运算的东西Rational(这就是它fromIntegral正在做的事情).


Jon*_*ast 7

因为整数的除法运算符有两个结果(商和余数):

divMod :: Integer -> Integer -> (Integer, Integer)
Run Code Online (Sandbox Code Playgroud)

您还可以使用div运算符:

n `div` m
Run Code Online (Sandbox Code Playgroud)

它仅返回除法结果的一个组成部分(商),但这与 不同n / m/适用于除法运算符只有一个结果的类型,该结果将“商”和“余数”组合成一个分数。

等式地,如果(q, r) = n `divMod` m,那么

n = m * q + r
Run Code Online (Sandbox Code Playgroud)

而如果q = x / y, 那么

x = y * q
Run Code Online (Sandbox Code Playgroud)

(关于浮点数和近似值的常见警告)。

替换div/破坏这种关系,因为它会丢弃一些您需要重现的信息n