Skip to content

Commit 8f3e5e4

Browse files
committed
Merge pull request purescript#872 from purescript/num
Revise Num class hierarchy
2 parents 9aa8b92 + 09bd21d commit 8f3e5e4

File tree

8 files changed

+170
-67
lines changed

8 files changed

+170
-67
lines changed

examples/passing/OneConstructor.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ module Main where
22

33
data One a = One a
44

5-
one (One a) = a
5+
one' (One a) = a
66

77
main = Debug.Trace.trace "Done"

examples/passing/Rank2Data.purs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ module Main where
1212
runNat = \nat -> case nat of
1313
Nat f -> f 0 (\n -> n + 1)
1414

15-
zero = Nat (\zero _ -> zero)
15+
zero' = Nat (\zero' _ -> zero')
1616

1717
succ = \n -> case n of
18-
Nat f -> Nat (\zero succ -> succ (f zero succ))
18+
Nat f -> Nat (\zero' succ -> succ (f zero' succ))
1919

2020
add = \n m -> case n of
2121
Nat f -> case m of
22-
Nat g -> Nat (\zero succ -> g (f zero succ) succ)
22+
Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
2323

24-
one = succ zero
25-
two = succ zero
24+
one' = succ zero'
25+
two = succ zero'
2626
four = add two two
2727
fourNumber = runNat four
2828

29-
main = Debug.Trace.trace "Done"
29+
main = Debug.Trace.trace "Done'"

examples/passing/ShadowedTCO.purs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ module Main where
22

33
runNat f = f 0 (\n -> n + 1)
44

5-
zero z _ = z
5+
zero' z _ = z
66

7-
succ f zero succ = succ (f zero succ)
7+
succ f zero' succ = succ (f zero' succ)
88

9-
add f g zero succ = g (f zero succ) succ
9+
add f g zero' succ = g (f zero' succ) succ
1010

11-
one = succ zero
12-
two = succ one
11+
one' = succ zero'
12+
two = succ one'
1313
four = add two two
1414
fourNumber = runNat four
1515

prelude/README.md

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@
5959
class (Semigroupoid a) <= Category a where
6060
id :: forall t. a t t
6161

62+
#### `DivisionRing`
63+
64+
Ring where every nonzero element has a multiplicative inverse (possibly
65+
a non-commutative field) so that ```a `mod` b = zero```
66+
67+
class (ModuloRing a) <= DivisionRing a where
68+
6269
#### `Eq`
6370

6471
class Eq a where
@@ -70,25 +77,37 @@
7077
class Functor f where
7178
(<$>) :: forall a b. (a -> b) -> f a -> f b
7279

80+
#### `ModuloRing`
81+
82+
Ring with modulo operation and division where
83+
```a / b * b + (a `mod` b) = a```
84+
85+
class (Ring a) <= ModuloRing a where
86+
(/) :: a -> a -> a
87+
mod :: a -> a -> a
88+
7389
#### `Monad`
7490

7591
class (Applicative m, Bind m) <= Monad m where
7692

7793
#### `Num`
7894

79-
class Num a where
80-
(+) :: a -> a -> a
81-
(-) :: a -> a -> a
82-
(*) :: a -> a -> a
83-
(/) :: a -> a -> a
84-
(%) :: a -> a -> a
85-
negate :: a -> a
95+
A commutative field
96+
97+
class (DivisionRing a) <= Num a where
8698

8799
#### `Ord`
88100

89101
class (Eq a) <= Ord a where
90102
compare :: a -> a -> Ordering
91103

104+
#### `Ring`
105+
106+
Addition, multiplication, and subtraction
107+
108+
class (Semiring a) <= Ring a where
109+
(-) :: a -> a -> a
110+
92111
#### `Semigroup`
93112

94113
class Semigroup a where
@@ -99,6 +118,16 @@
99118
class Semigroupoid a where
100119
(<<<) :: forall b c d. a c d -> a b c -> a b d
101120

121+
#### `Semiring`
122+
123+
Addition and multiplication
124+
125+
class Semiring a where
126+
(+) :: a -> a -> a
127+
zero :: a
128+
(*) :: a -> a -> a
129+
one :: a
130+
102131
#### `Show`
103132

104133
class Show a where
@@ -131,6 +160,10 @@
131160

132161
instance categoryArr :: Category Prim.Function
133162

163+
#### `divisionRingNumber`
164+
165+
instance divisionRingNumber :: DivisionRing Number
166+
134167
#### `eqArray`
135168

136169
instance eqArray :: (Eq a) => Eq [a]
@@ -159,6 +192,10 @@
159192

160193
instance functorArr :: Functor (Prim.Function r)
161194

195+
#### `moduloRingNumber`
196+
197+
instance moduloRingNumber :: ModuloRing Number
198+
162199
#### `monadArr`
163200

164201
instance monadArr :: Monad (Prim.Function r)
@@ -187,6 +224,10 @@
187224

188225
instance ordUnit :: Ord Unit
189226

227+
#### `ringNumber`
228+
229+
instance ringNumber :: Ring Number
230+
190231
#### `semigroupArr`
191232

192233
instance semigroupArr :: (Semigroup s') => Semigroup (s -> s')
@@ -203,6 +244,10 @@
203244

204245
instance semigroupoidArr :: Semigroupoid Prim.Function
205246

247+
#### `semiringNumber`
248+
249+
instance semiringNumber :: Semiring Number
250+
206251
#### `showArray`
207252

208253
instance showArray :: (Show a) => Show [a]
@@ -277,7 +322,7 @@
277322
#### `asTypeOf`
278323

279324
This function returns its first argument, and can be used to assert type equalities.
280-
This can be useful when types are otherwise ambiguous.
325+
This can be useful when types are otherwise ambiguous.
281326

282327
E.g.
283328

@@ -294,13 +339,13 @@ been ambiguous, resulting in a compile-time error.
294339

295340
#### `const`
296341

297-
Returns its first argument and ignores its second.
342+
Returns its first argument and ignores its second.
298343

299344
const :: forall a b. a -> b -> a
300345

301346
#### `flip`
302347

303-
Flips the order of the arguments to a function of two arguments.
348+
Flips the order of the arguments to a function of two arguments.
304349

305350
flip :: forall a b c. (a -> b -> c) -> b -> a -> c
306351

@@ -312,13 +357,17 @@ Flips the order of the arguments to a function of two arguments.
312357

313358
liftM1 :: forall m a b. (Monad m) => (a -> b) -> m a -> m b
314359

360+
#### `negate`
361+
362+
negate :: forall a. (Ring a) => a -> a
363+
315364
#### `otherwise`
316365

317-
An alias for `true`, which can be useful in guard clauses:
366+
An alias for `true`, which can be useful in guard clauses:
318367

319368
E.g.
320369

321-
max x y | x >= y = x
370+
max x y | x >= y = x
322371
| otherwise = y
323372

324373
otherwise :: Boolean

prelude/prelude.purs

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ module Prelude
1313
, Applicative, pure, liftA1
1414
, Bind, (>>=)
1515
, Monad, return, liftM1, ap
16-
, Num, (+), (-), (*), (/), (%)
16+
, Semiring, (+), zero, (*), one
17+
, Ring, (-)
18+
, (%)
1719
, negate
20+
, ModuloRing, (/), mod
21+
, DivisionRing
22+
, Num
1823
, Eq, (==), (/=), refEq, refIneq
1924
, Ord, Ordering(..), compare, (<), (>), (<=), (>=)
2025
, Bits, (.&.), (.|.), (.^.), shl, shr, zshr, complement
@@ -24,28 +29,28 @@ module Prelude
2429
, Unit(..), unit
2530
) where
2631

27-
-- | An alias for `true`, which can be useful in guard clauses:
28-
-- |
32+
-- | An alias for `true`, which can be useful in guard clauses:
33+
-- |
2934
-- | E.g.
30-
-- |
31-
-- | max x y | x >= y = x
35+
-- |
36+
-- | max x y | x >= y = x
3237
-- | | otherwise = y
3338
otherwise :: Boolean
3439
otherwise = true
3540

36-
-- | Flips the order of the arguments to a function of two arguments.
41+
-- | Flips the order of the arguments to a function of two arguments.
3742
flip :: forall a b c. (a -> b -> c) -> b -> a -> c
3843
flip f b a = f a b
3944

40-
-- | Returns its first argument and ignores its second.
45+
-- | Returns its first argument and ignores its second.
4146
const :: forall a b. a -> b -> a
4247
const a _ = a
4348

4449
-- | This function returns its first argument, and can be used to assert type equalities.
45-
-- | This can be useful when types are otherwise ambiguous.
46-
-- |
50+
-- | This can be useful when types are otherwise ambiguous.
51+
-- |
4752
-- | E.g.
48-
-- |
53+
-- |
4954
-- | main = print $ [] `asTypeOf` [0]
5055
-- |
5156
-- | If instead, we had written `main = print []`, the type of the argument `[]` would have
@@ -205,13 +210,32 @@ module Prelude
205210
infixl 6 -
206211
infixl 6 +
207212

208-
class Num a where
209-
(+) :: a -> a -> a
213+
-- | Addition and multiplication
214+
class Semiring a where
215+
(+) :: a -> a -> a
216+
zero :: a
217+
(*) :: a -> a -> a
218+
one :: a
219+
220+
-- | Addition, multiplication, and subtraction
221+
class (Semiring a) <= Ring a where
210222
(-) :: a -> a -> a
211-
(*) :: a -> a -> a
223+
224+
negate :: forall a. (Ring a) => a -> a
225+
negate a = zero - a
226+
227+
-- | Ring with modulo operation and division where
228+
-- | ```a / b * b + (a `mod` b) = a```
229+
class (Ring a) <= ModuloRing a where
212230
(/) :: a -> a -> a
213-
(%) :: a -> a -> a
214-
negate :: a -> a
231+
mod :: a -> a -> a
232+
233+
-- | Ring where every nonzero element has a multiplicative inverse (possibly
234+
-- | a non-commutative field) so that ```a `mod` b = zero```
235+
class (ModuloRing a) <= DivisionRing a
236+
237+
-- | A commutative field
238+
class (DivisionRing a) <= Num a
215239

216240
foreign import numAdd
217241
"""
@@ -258,20 +282,24 @@ module Prelude
258282
}
259283
""" :: Number -> Number -> Number
260284

261-
foreign import numNegate
262-
"""
263-
function numNegate(n) {
264-
return -n;
265-
}
266-
""" :: Number -> Number
285+
(%) = numMod
267286

268-
instance numNumber :: Num Number where
287+
instance semiringNumber :: Semiring Number where
269288
(+) = numAdd
270-
(-) = numSub
289+
zero = 0
271290
(*) = numMul
291+
one = 1
292+
293+
instance ringNumber :: Ring Number where
294+
(-) = numSub
295+
296+
instance moduloRingNumber :: ModuloRing Number where
272297
(/) = numDiv
273-
(%) = numMod
274-
negate = numNegate
298+
mod _ _ = 0
299+
300+
instance divisionRingNumber :: DivisionRing Number
301+
302+
instance numNumber :: Num Number
275303

276304
newtype Unit = Unit {}
277305

src/Language/PureScript/CodeGen/JS/Optimizer.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ optimize opts | optionsNoOptimizations opts = id
6363
, etaConvert
6464
, evaluateIifes
6565
, inlineVariables
66+
, inlineValues
6667
, inlineOperator (C.prelude, (C.$)) $ \f x -> JSApp f [x]
6768
, inlineOperator (C.prelude, (C.#)) $ \x f -> JSApp f [x]
6869
, inlineOperator (C.preludeUnsafe, C.unsafeIndex) $ flip JSIndexer

0 commit comments

Comments
 (0)