A categorical programming language
修訂 | de203222d444a26d5f4b5ea9b4b6884ba50cb824 (tree) |
---|---|
時間 | 2022-11-28 07:34:34 |
作者 | Corbin <cds@corb...> |
Commiter | Corbin |
Finish switching over to PureScript.
This is very messy and I'm not really pleased with it. The overall
speedup that I was hoping for? Not there!
@@ -24,7 +24,7 @@ bind f (Pure x) = f x | ||
24 | 24 | bind f (Free thunk) = Free (\u -> bind f (thunk u)) |
25 | 25 | |
26 | 26 | join :: forall t. Tramp (Tramp t) -> Tramp t |
27 | -join = bind id | |
27 | +join = bind (\x -> x) | |
28 | 28 | |
29 | 29 | -- This function will be called to evaluate "toplevel" expressions |
30 | 30 | runTrampoline :: forall t. Tramp t -> t |
@@ -34,6 +34,9 @@ runTrampoline (Free thunk) = runTrampoline (thunk Unit) | ||
34 | 34 | lift :: forall s t. (s -> t) -> s -> Tramp t |
35 | 35 | lift f x = Pure (f x) |
36 | 36 | |
37 | +lift2 :: forall s t u. (s -> t -> u) -> Pair s t -> Tramp u | |
38 | +lift2 f (Pair x y) = Pure (f x y) | |
39 | + | |
37 | 40 | -- Cammy core types |
38 | 41 | data Pair s t = Pair s t |
39 | 42 | data Either s t = Left s | Right t |
@@ -43,33 +46,33 @@ makePair = Pair | ||
43 | 46 | |
44 | 47 | -- Cammy core primitives |
45 | 48 | |
46 | -id :: forall t. t -> t | |
47 | -id x = x | |
49 | +id :: forall t. t -> Tramp t | |
50 | +id = done | |
48 | 51 | |
49 | -ignore :: forall t. t -> Unit | |
50 | -ignore _ = Unit | |
52 | +ignore :: forall t. t -> Tramp Unit | |
53 | +ignore _ = done Unit | |
51 | 54 | |
52 | -fst :: forall s t. Pair s t -> s | |
53 | -fst (Pair x _) = x | |
55 | +fst :: forall s t. Pair s t -> Tramp s | |
56 | +fst (Pair x _) = done x | |
54 | 57 | |
55 | -snd :: forall s t. Pair s t -> t | |
56 | -snd (Pair _ y) = y | |
58 | +snd :: forall s t. Pair s t -> Tramp t | |
59 | +snd (Pair _ y) = done y | |
57 | 60 | |
58 | -dup :: forall t. t -> Pair t t | |
59 | -dup x = Pair x x | |
61 | +dup :: forall t. t -> Tramp (Pair t t) | |
62 | +dup x = done (Pair x x) | |
60 | 63 | |
61 | 64 | app :: forall s t. Pair (s -> Tramp t) s -> Tramp t |
62 | 65 | app (Pair f x) = f x |
63 | 66 | |
64 | -left :: forall s t. s -> Either s t | |
65 | -left = Left | |
67 | +left :: forall s t. s -> Tramp (Either s t) | |
68 | +left = lift Left | |
66 | 69 | |
67 | -right :: forall s t. t -> Either s t | |
68 | -right = Right | |
70 | +right :: forall s t. t -> Tramp (Either s t) | |
71 | +right = lift Right | |
69 | 72 | |
70 | -either :: Boolean -> Either Unit Unit | |
71 | -either true = Left Unit | |
72 | -either false = Right Unit | |
73 | +either :: Boolean -> Tramp (Either Unit Unit) | |
74 | +either true = done (Left Unit) | |
75 | +either false = done (Right Unit) | |
73 | 76 | |
74 | 77 | foreign import natAdd :: Int -> Int -> Int |
75 | 78 | foreign import natIsZero :: Int -> Boolean |
@@ -127,8 +130,11 @@ conj :: Pair Boolean Boolean -> Tramp Boolean | ||
127 | 130 | conj (Pair true true) = done true |
128 | 131 | conj _ = done false |
129 | 132 | |
130 | --- fixNaN x = if isNaN x then right (ignore Unit) else left x | |
131 | --- rescueNaN f x = fixNaN (f x) | |
133 | +foreign import butIsNaN :: Number -> Boolean | |
134 | + | |
135 | +fixNaN :: Number -> Tramp (Either Number Unit) | |
136 | +fixNaN x = if butIsNaN x then right Unit else left x | |
137 | +rescueNaN f x = fixNaN (f x) | |
132 | 138 | |
133 | 139 | foreign import natZero :: Unit -> Int |
134 | 140 | foreign import natSucc :: Int -> Int |
@@ -152,3 +158,43 @@ foreign import listCons :: forall t. t -> Array t -> Array t | ||
152 | 158 | |
153 | 159 | cons :: forall t. Pair t (Array t) -> Tramp (Array t) |
154 | 160 | cons (Pair x xs) = done (listCons x xs) |
161 | + | |
162 | +foreign import fZero :: Unit -> Number | |
163 | +foreign import fOne :: Unit -> Number | |
164 | +foreign import fPi :: Unit -> Number | |
165 | +foreign import fAdd :: Number -> Number -> Number | |
166 | +foreign import fMul :: Number -> Number -> Number | |
167 | +foreign import fLT :: Number -> Number -> Boolean | |
168 | +foreign import fCos :: Number -> Number | |
169 | +foreign import fSin :: Number -> Number | |
170 | +foreign import fNegate :: Number -> Number | |
171 | + | |
172 | +f'zero :: Unit -> Tramp Number | |
173 | +f'zero = lift fZero | |
174 | + | |
175 | +f'one :: Unit -> Tramp Number | |
176 | +f'one = lift fOne | |
177 | + | |
178 | +f'pi :: Unit -> Tramp Number | |
179 | +f'pi = lift fPi | |
180 | + | |
181 | +f'add (Pair x y) = done (fAdd x y) | |
182 | +f'mul (Pair x y) = done (fMul x y) | |
183 | +f'lt (Pair x y) = done (fLT x y) | |
184 | +f'cos = lift fCos | |
185 | +f'sin = lift fSin | |
186 | + | |
187 | +f'negate = lift fNegate | |
188 | + | |
189 | +foreign import fATan2 :: Number -> Number -> Number | |
190 | +foreign import fRecip :: Number -> Number | |
191 | +foreign import fSign :: Number -> Boolean | |
192 | +foreign import fFloor :: Number -> Number | |
193 | +foreign import fSqrt :: Number -> Number | |
194 | + | |
195 | +f'atan2 = lift2 fATan2 | |
196 | +f'recip = lift fRecip | |
197 | +f'sign = lift fSign | |
198 | + | |
199 | +f'floor x = done (rescueNaN fFloor x) | |
200 | +f'sqrt x = done (rescueNaN fSqrt x) |
@@ -132,7 +132,9 @@ def compilePurescriptStub(token): | ||
132 | 132 | handle.write(PURS_STUB) |
133 | 133 | handle.write("\nmain = ") |
134 | 134 | # purs can't handle hyphens in function names! |
135 | - handle.write(sexpify(expr).replace("-", "'")) | |
135 | + # Also `case` is reserved. | |
136 | + sexp = sexpify(expr).replace("-", "'").replace("case", "caseOf") | |
137 | + handle.write(sexp) | |
136 | 138 | handle.write("\n\n") |
137 | 139 | subprocess.check_output([PURESCRIPT + "purs", "compile", "-o", "/tmp/", "/tmp/cammy.purs"]) |
138 | 140 | with open("/tmp/Cammy/index.js") as handle: |
@@ -1,20 +1,22 @@ | ||
1 | 1 | export const natZero = _ => 0; |
2 | 2 | export const natSucc = n => n + 1; |
3 | 3 | |
4 | -// "f-zero": _ => 0.0, | |
5 | -// "f-one": _ => 1.0, | |
6 | -// "f-pi": _ => Math.PI, | |
7 | -// "f-add": xy => Cammy.fst(xy) + Cammy.snd(xy), | |
8 | -// "f-mul": xy => Cammy.fst(xy) * Cammy.snd(xy), | |
9 | -// "f-negate": x => -x, | |
10 | -// "f-recip": x => 1 / x, | |
11 | -// "f-sign": x => x <= -0.0, | |
12 | -// "f-floor": rescueNaN(Math.floor), | |
13 | -// "f-sqrt": rescueNaN(Math.sqrt), | |
14 | -// "f-lt": xy => Cammy.fst(xy) < Cammy.snd(xy), | |
15 | -// "f-sin": x => Number.isFinite(x) ? Math.sin(x) : 0.0, | |
16 | -// "f-cos": x => Number.isFinite(x) ? Math.cos(x) : 0.0, | |
17 | -// "f-atan2": yx => Math.atan2(Cammy.fst(yx), Cammy.snd(yx)), | |
4 | +export const fZero = _ => 0.0; | |
5 | +export const fOne = _ => 1.0; | |
6 | +export const fPi = _ => Math.PI; | |
7 | +export const fAdd = x => y => x + y; | |
8 | +export const fMul = x => y => x * y; | |
9 | +export const fLT = x => y => x < y; | |
10 | +export const fSin = x => Number.isFinite(x) ? Math.sin(x) : 0.0; | |
11 | +export const fCos = x => Number.isFinite(x) ? Math.cos(x) : 0.0; | |
12 | +export const fATan2 = y => x => Math.atan2(y, x); | |
13 | +export const fNegate = x => -x; | |
14 | +export const fRecip = x => 1 / x; | |
15 | +export const fSign = x => x <= -0.0; | |
16 | + | |
17 | +export const butIsNaN = x => isNaN(x); | |
18 | +export const fFloor = Math.floor; | |
19 | +export const fSqrt = Math.sqrt; | |
18 | 20 | |
19 | 21 | export const intSub = x => y => x - y; |
20 | 22 |