Consider this short GHCi session:
ghci> import Data.Ratio
ghci> import Data.Word
ghci> 128 % 3 + 127 % 3 :: Ratio Word8
253 % 9
Why is the result 253 % 9
and not 255 % 3 (= 85 % 1)
?
That, really, is my question, but I'll be happy to elaborate.
First, if I remove the type, the result is what I'd expect:
ghci> 128 % 3 + 127 % 3
85 % 1
The type Word8
seems important. I'm aware of potential integer overflow, but even so, I can't make sense of the result. E.g.
ghci> 128 + 127 :: Word8
255
There's no overflow here. That first happens at
ghci> 128 + 128 :: Word8
0
ghci> 128 + 129 :: Word8
1
If I divide by two instead of three, I can still comprehend the results:
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
Here 128 % 2 + 128 % 2
even produces 128 % 1
as one would hope. All of this seems to make perfect sense as 'normal' modulo-256 arithmetic, but then what happens when I work in thirds instead of halves? Why is the denominator 9
?
It's because addition for the rationals is defined as
(x:%y) + (x':%y') = reduce (x*y' + x'*y) (y*y')
Since everything here is Word8
, each individual operation is performed mod 256
.
(128*3) `mod` 256 = 128
(127*3) `mod` 256 = 125
(128+125) `mod` 256 = 253