为什么在 Haskell 中添加两个有理数时会得到这个结果

Mar*_*ann 5 rational-number haskell

考虑这个简短的 GHCi 会议:

ghci> import Data.Ratio
ghci> import Data.Word
ghci> 128 % 3 + 127 % 3 :: Ratio Word8
253 % 9
Run Code Online (Sandbox Code Playgroud)

为什么结果是253 % 9而不是255 % 3 (= 85 % 1)

这确实是我的问题,但我很乐意详细说明。


首先,如果我删除类型,结果就是我所期望的:

ghci> 128 % 3 + 127 % 3
85 % 1
Run Code Online (Sandbox Code Playgroud)

类型Word8似乎很重要。我知道潜在的整数溢出,但即便如此,我也无法理解结果。例如

ghci> 128 + 127 :: Word8
255
Run Code Online (Sandbox Code Playgroud)

这里没有溢出。这首先发生在

ghci> 128 + 128 :: Word8
0
ghci> 128 + 129 :: Word8
1
Run Code Online (Sandbox Code Playgroud)

如果我除以二而不是三,我仍然可以理解结果:

ghci> 128 % 2 + 127 % 2 :: Ratio Word8
255 % 2
ghci> 128 % 2 + 128 % 2 :: Ratio Word8
128 % 1
ghci> 128 % 2 + 129 % 2 :: Ratio Word8
1 % 2
ghci> 129 % 2 + 129 % 2 :: Ratio Word8
1 % 1
Run Code Online (Sandbox Code Playgroud)

这里128 % 2 + 128 % 2甚至产生了128 % 1人们所希望的结果。所有这些似乎都作为“正常”模 256 算术完全有意义,但是当我以三分之一而不是一半计算时会发生什么?为什么是分母9

n. *_* m. 5

这是因为有理数的加法定义为

(x:%y) + (x':%y')   =  reduce (x*y' + x'*y) (y*y')
Run Code Online (Sandbox Code Playgroud)

既然这里的一切都是如此Word8,那么每一个操作都是单独执行的mod 256

(128*3)   `mod` 256 = 128
(127*3)   `mod` 256 = 125
(128+125) `mod` 256 = 253 
Run Code Online (Sandbox Code Playgroud)

  • @MarkSeemann:我认为“Ratio”类型的数据构造函数? (2认同)