Skip to content

Commit 712a5e2

Browse files
authored
Merge pull request #31 from purescript/field-parity
Add Field Parity instance, resolves #30
2 parents 4ef3a1e + 7145f6a commit 712a5e2

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/Data/Int.purs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ fromString :: String -> Maybe Int
8080
fromString = fromStringAs (Radix 10)
8181

8282
-- | A type for describing whether an integer is even or odd.
83+
-- |
84+
-- | The `Ord` instance considers `Even` to be less than `Odd`.
85+
-- |
86+
-- | The `Semiring` instance allows you to ask about the parity of the results
87+
-- | of arithmetical operations, given only the parities of the inputs. For
88+
-- | example, the sum of an odd number and an even number is odd, so
89+
-- | `Odd + Even == Odd`. This also works for multiplication, eg. the product
90+
-- | of two odd numbers is odd, and therefore `Odd * Odd == Odd`.
91+
-- |
92+
-- | More generally, we have that
93+
-- |
94+
-- | ```purescript
95+
-- | parity x + parity y == parity (x + y)
96+
-- | parity x * parity y == parity (x * y)
97+
-- | ```
98+
-- |
99+
-- | for any integers `x`, `y`. (A mathematician would say that `parity` is a
100+
-- | *ring homomorphism*.)
101+
-- |
102+
-- | After defining addition and multiplication on `Parity` in this way, the
103+
-- | `Semiring` laws now force us to choose `zero = Even` and `one = Odd`.
104+
-- | This `Semiring` instance actually turns out to be a `Field`.
83105
data Parity = Even | Odd
84106

85107
derive instance eqParity :: Eq Parity
@@ -93,6 +115,29 @@ instance boundedParity :: Bounded Parity where
93115
bottom = Even
94116
top = Odd
95117

118+
instance semiringParity :: Semiring Parity where
119+
zero = Even
120+
add x y = if x == y then Even else Odd
121+
one = Odd
122+
mul Odd Odd = Odd
123+
mul _ _ = Even
124+
125+
instance ringParity :: Ring Parity where
126+
sub = add
127+
128+
instance commutativeRingParity :: CommutativeRing Parity
129+
130+
instance euclideanRingParity :: EuclideanRing Parity where
131+
degree Even = 0
132+
degree Odd = 1
133+
div x _ = x
134+
mod _ _ = Even
135+
136+
instance divisionRingParity :: DivisionRing Parity where
137+
recip = id
138+
139+
instance fieldParity :: Field Parity
140+
96141
-- | Returns whether an `Int` is `Even` or `Odd`.
97142
-- |
98143
-- | ``` purescript

test/Test/Data/Int.purs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Prelude
55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (CONSOLE, log)
77

8-
import Data.Int (odd, even, fromString, floor, ceil, round, toNumber, fromNumber, fromStringAs, binary, octal, hexadecimal, radix, toStringAs, pow)
8+
import Data.Int (parity, odd, even, fromString, floor, ceil, round, toNumber, fromNumber, fromStringAs, binary, octal, hexadecimal, radix, toStringAs, pow)
99
import Data.Maybe (Maybe(..), fromJust)
1010

1111
import Global (nan, infinity)
@@ -136,6 +136,21 @@ testInt = do
136136
assert $ odd 4 == false
137137
assert $ odd 100 == false
138138

139+
log "parity is a ring homomorphism"
140+
do
141+
let go x y = do
142+
assert $ parity x + parity y == parity (x + y)
143+
assert $ parity x * parity y == parity (x * y)
144+
145+
go 0 0
146+
go 0 1
147+
go 1 0
148+
go 1 1
149+
go 2 28
150+
go 2 3
151+
go 3 8
152+
go 49 171
153+
139154
log "pow"
140155
assert $ pow 2 2 == 4
141156
assert $ pow 5 3 == 125

0 commit comments

Comments
 (0)