-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patharithmetic.coffee
94 lines (80 loc) · 1.25 KB
/
arithmetic.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# vim: set noexpandtab:
#
# Identity function
id = (x) -> x
# Define zero
_0 = id
# Define increment-decrement
incr = (x) -> (y) -> y x
decr = (x) -> x _0
# Define one
_1 = incr _0
# Define isZero condition (black magic)
isZero = (num) -> _1(num(True True))
# Define equality
eq = Y((eq) ->
(x) -> (y) -> If( isZero x )(
(z) -> isZero y
)(
(z) -> If( isZero y )(
(z) -> False
)(
(z) -> eq(decr x)(decr y)
)
)
)
# Define less than
lt = Y((lt) ->
(x) -> (y) -> If( isZero x )(
(z) -> Not isZero y
)(
(z) -> lt(decr x)(decr y)
)
)
# Define greater than
gt = (x) -> (y) -> Not Or(eq(x)(y))(lt(x)(y))
# Define addition
add = Y((add) ->
(x) -> (y) -> If( isZero x )(
(z) -> y
)(
(z) -> add(decr x)(incr y)
)
)
# Define subtraction
sub = Y((sub) ->
(x) -> (y) -> If( isZero y )(
(z) -> x
)(
(z) -> sub(decr x)(decr y)
)
)
# Define multiplication
mul = Y((mul) ->
(x) -> (y) -> If( isZero x )(
(z) -> _0
)(
(z) ->
If( eq(x)(_1) )(
(z) -> y
)(
(z) -> add(mul(decr x)(y))(y)
)
)
)
# Define modulo
mod = Y((mod) ->
(x) -> (y) -> If( lt(x)(y) )(
(z) -> x
)(
(z) -> mod(sub(x)(y))(y)
)
)
# Define division
div = Y((div) ->
(x) -> (y) -> If( lt(x)(y) )(
(z) -> _0
)(
(z) -> incr(div(sub(x)(y))(y))
)
)