Skip to content

Commit 9732688

Browse files
authored
Merge pull request #107 from purescript/rework-euclidean-ring
Rework EuclideanRing laws, fixes #99, #102
2 parents 2bff6d7 + 524fcef commit 9732688

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/Data/EuclideanRing.purs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,37 @@ import Data.Semiring (class Semiring, add, mul, one, zero, (*), (+))
1111
import Data.Unit (Unit, unit)
1212

1313
-- | The `EuclideanRing` class is for commutative rings that support division.
14+
-- | The mathematical structure this class is based on is sometimes also called
15+
-- | a *Euclidean domain*.
1416
-- |
15-
-- | Instances must satisfy the following law in addition to the `Ring`
17+
-- | Instances must satisfy the following laws in addition to the `Ring`
1618
-- | laws:
1719
-- |
18-
-- | - Integral domain: `a /= 0` and `b /= 0` implies `a * b /= 0`
19-
-- | - Multiplicative Euclidean function: ``a = (a / b) * b + (a `mod` b)``
20-
-- | where `degree a > 0` and `degree a <= degree (a * b)`
20+
-- | - Integral domain: `one /= zero`, and if `a` and `b` are both nonzero then
21+
-- | so is their product `a * b`
22+
-- | - Euclidean function `degree`:
23+
-- | - Nonnegativity: For all nonzero `a`, `degree a >= 0`
24+
-- | - Quotient/remainder: For all `a` and `b`, where `b` is nonzero,
25+
-- | let `q = a / b` and ``r = a `mod` b``; then `a = q*b + r`, and also
26+
-- | either `r = zero` or `degree r < degree b`
27+
-- | - Submultiplicative euclidean function:
28+
-- | - For all nonzero `a` and `b`, `degree a <= degree (a * b)`
29+
-- |
30+
-- | The behaviour of division by `zero` is unconstrained by these laws,
31+
-- | meaning that individual instances are free to choose how to behave in this
32+
-- | case. Similarly, there are no restrictions on what the result of
33+
-- | `degree zero` is; it doesn't make sense to ask for `degree zero` in the
34+
-- | same way that it doesn't make sense to divide by `zero`, so again,
35+
-- | individual instances may choose how to handle this case.
36+
-- |
37+
-- | For any `EuclideanRing` which is also a `Field`, one valid choice
38+
-- | for `degree` is simply `const 1`. In fact, unless there's a specific
39+
-- | reason not to, `Field` types should normally use this definition of
40+
-- | `degree`.
41+
-- |
42+
-- | The `Unit` instance is provided for backwards compatibility, but it is
43+
-- | not law-abiding, because `Unit` fails to form an integral domain. This
44+
-- | instance will be removed in a future release.
2145
class CommutativeRing a <= EuclideanRing a where
2246
degree :: a -> Int
2347
div :: a -> a -> a

src/Data/Field.purs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import Data.Unit (Unit)
1818
-- | `EuclideanRing` laws:
1919
-- |
2020
-- | - Non-zero multiplicative inverse: ``a `mod` b = zero`` for all `a` and `b`
21+
-- |
22+
-- | The `Unit` instance is provided for backwards compatibility, but it is
23+
-- | not law-abiding, because `Unit` does not obey the `EuclideanRing` laws.
24+
-- | This instance will be removed in a future release.
2125
class EuclideanRing a <= Field a
2226

2327
instance fieldNumber :: Field Number

0 commit comments

Comments
 (0)