@@ -2,9 +2,13 @@ module Data.EuclideanRing
22 ( class EuclideanRing , degree , div , mod , (/)
33 , gcd
44 , lcm
5+ , quot
6+ , rem
57 , module Data.CommutativeRing
68 , module Data.Ring
79 , module Data.Semiring
10+ , intDiv
11+ , intMod
812 ) where
913
1014import Data.BooleanAlgebra ((||))
@@ -41,6 +45,25 @@ import Data.Semiring (class Semiring, add, mul, one, zero, (*), (+))
4145-- | for `degree` is simply `const 1`. In fact, unless there's a specific
4246-- | reason not to, `Field` types should normally use this definition of
4347-- | `degree`.
48+ -- |
49+ -- | The `EuclideanRing Int` instance is one of the most commonly used
50+ -- | `EuclideanRing` instances and deserves a little more discussion. In
51+ -- | particular, there are a few different sensible law-abiding implementations
52+ -- | to choose from, with slightly different behaviour in the presence of
53+ -- | negative dividends or divisors. The most common definitions are "truncating"
54+ -- | division, where the result of `a / b` is rounded towards 0, and "Knuthian"
55+ -- | or "flooring" division, where the result of `a / b` is rounded towards
56+ -- | negative infinity. A slightly less common, but arguably more useful, option
57+ -- | is "Euclidean" division, which is defined so as to ensure that ``a `mod` b``
58+ -- | is always nonnegative. With Euclidean division, `a / b` rounds towards
59+ -- | negative infinity if the divisor is positive, and towards positive infinity
60+ -- | if the divisor is negative. Note that all three definitions are identical if
61+ -- | we restrict our attention to nonnegative dividends and divisors.
62+ -- |
63+ -- | In versions 1.x, 2.x, and 3.x of the Prelude, the `EuclideanRing Int`
64+ -- | instance used truncating division. As of 4.x, the `EuclideanRing Int`
65+ -- | instance uses Euclidean division. Additional functions `quot` and `rem` are
66+ -- | supplied if truncating division is desired.
4467class CommutativeRing a <= EuclideanRing a where
4568 degree :: a -> Int
4669 div :: a -> a -> a
@@ -77,3 +100,38 @@ lcm a b =
77100 if a == zero || b == zero
78101 then zero
79102 else a * b / gcd a b
103+
104+ -- | The `quot` function provides _truncating_ integer division (see the
105+ -- | documentation for the `EuclideanRing` class). It is identical to `div` in
106+ -- | the `EuclideanRing Int` instance if the dividend is positive, but will be
107+ -- | slightly different if the dividend is negative. For example:
108+ -- |
109+ -- | ```purescript
110+ -- | div 2 3 == 0
111+ -- | quot 2 3 == 0
112+ -- |
113+ -- | div (-2) 3 == (-1)
114+ -- | quot (-2) 3 == 0
115+ -- |
116+ -- | div 2 (-3) == 0
117+ -- | quot 2 (-3) == 0
118+ -- | ```
119+ foreign import quot :: Int -> Int -> Int
120+
121+ -- | The `rem` function provides the remainder after _truncating_ integer
122+ -- | division (see the documentation for the `EuclideanRing` class). It is
123+ -- | identical to `mod` in the `EuclideanRing Int` instance if the dividend is
124+ -- | positive, but will be slightly different if the dividend is negative. For
125+ -- | example:
126+ -- |
127+ -- | ```purescript
128+ -- | mod 2 3 == 2
129+ -- | rem 2 3 == 2
130+ -- |
131+ -- | mod (-2) 3 == 1
132+ -- | rem (-2) 3 == (-2)
133+ -- |
134+ -- | mod 2 (-3) == 2
135+ -- | rem 2 (-3) == 2
136+ -- | ```
137+ foreign import rem :: Int -> Int -> Int
0 commit comments