Skip to content

Commit cb64560

Browse files
authored
Merge pull request #130 from purescript/division-ring
Re-add DivisionRing, resolves #128
2 parents 9917c6e + 9e335e9 commit cb64560

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

src/Data/DivisionRing.purs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module Data.DivisionRing
2+
( class DivisionRing
3+
, recip
4+
, leftDiv
5+
, rightDiv
6+
, module Data.Ring
7+
, module Data.Semiring
8+
) where
9+
10+
import Data.Ring (class Ring, negate, sub)
11+
import Data.Semiring (class Semiring, add, mul, one, zero, (*), (+))
12+
import Data.EuclideanRing ((/))
13+
14+
-- | The `DivisionRing` class is for non-zero rings in which every non-zero
15+
-- | element has a multiplicative inverse. Division rings are sometimes also
16+
-- | called *skew fields*.
17+
-- |
18+
-- | Instances must satisfy the following laws in addition to the `Ring` laws:
19+
-- |
20+
-- | - Non-zero ring: `one /= zero`
21+
-- | - Non-zero multiplicative inverse: `recip a * a = a * recip a = one` for
22+
-- | all non-zero `a`
23+
-- |
24+
-- | The result of `recip zero` is left undefined; individual instances may
25+
-- | choose how to handle this case.
26+
-- |
27+
-- | If a type has both `DivisionRing` and `CommutativeRing` instances, then
28+
-- | it is a field and should have a `Field` instance.
29+
class Ring a <= DivisionRing a where
30+
recip :: a -> a
31+
32+
-- | Left division, defined as `leftDiv a b = recip b * a`. Left and right
33+
-- | division are distinct in this module because a `DivisionRing` is not
34+
-- | necessarily commutative.
35+
-- |
36+
-- | If the type `a` is also a `EuclideanRing`, then this function is
37+
-- | equivalent to `div` from the `EuclideanRing` class. When working
38+
-- | abstractly, `div` should generally be preferred, unless you know that you
39+
-- | need your code to work with noncommutative rings.
40+
leftDiv :: forall a. DivisionRing a => a -> a -> a
41+
leftDiv a b = recip b * a
42+
43+
-- | Right division, defined as `rightDiv a b = a * recip b`. Left and right
44+
-- | division are distinct in this module because a `DivisionRing` is not
45+
-- | necessarily commutative.
46+
-- |
47+
-- | If the type `a` is also a `EuclideanRing`, then this function is
48+
-- | equivalent to `div` from the `EuclideanRing` class. When working
49+
-- | abstractly, `div` should generally be preferred, unless you know that you
50+
-- | need your code to work with noncommutative rings.
51+
rightDiv :: forall a. DivisionRing a => a -> a -> a
52+
rightDiv a b = a * recip b
53+
54+
instance divisionringNumber :: DivisionRing Number where
55+
recip x = 1.0 / x

src/Data/Field.purs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
module Data.Field
22
( class Field
3+
, module Data.DivisionRing
34
, module Data.CommutativeRing
45
, module Data.EuclideanRing
56
, module Data.Ring
67
, module Data.Semiring
78
) where
89

10+
import Data.DivisionRing (class DivisionRing, recip)
911
import Data.CommutativeRing (class CommutativeRing)
1012
import Data.EuclideanRing (class EuclideanRing, degree, div, mod, (/), gcd, lcm)
1113
import Data.Ring (class Ring, negate, sub)
1214
import Data.Semiring (class Semiring, add, mul, one, zero, (*), (+))
1315

14-
-- | The `Field` class is for types that are commutative fields.
16+
-- | The `Field` class is for types that are (commutative) fields.
1517
-- |
1618
-- | Instances must satisfy the following law in addition to the
1719
-- | `EuclideanRing` laws:
1820
-- |
1921
-- | - Non-zero multiplicative inverse: ``a `mod` b = zero`` for all `a` and `b`
22+
-- |
23+
-- | If a type has a `Field` instance, it should also have a `DivisionRing`
24+
-- | instance. In a future release, `DivisionRing` may become a superclass of
25+
-- | `Field`.
2026
class EuclideanRing a <= Field a
2127

2228
instance fieldNumber :: Field Number

src/Prelude.purs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Prelude
99
, module Data.BooleanAlgebra
1010
, module Data.Bounded
1111
, module Data.CommutativeRing
12+
, module Data.DivisionRing
1213
, module Data.Eq
1314
, module Data.EuclideanRing
1415
, module Data.Field
@@ -37,6 +38,7 @@ import Data.Boolean (otherwise)
3738
import Data.BooleanAlgebra (class BooleanAlgebra)
3839
import Data.Bounded (class Bounded, bottom, top)
3940
import Data.CommutativeRing (class CommutativeRing)
41+
import Data.DivisionRing (class DivisionRing, recip)
4042
import Data.Eq (class Eq, eq, notEq, (/=), (==))
4143
import Data.EuclideanRing (class EuclideanRing, degree, div, mod, (/), gcd, lcm)
4244
import Data.Field (class Field)

0 commit comments

Comments
 (0)