blob: dfe93023ab0f01c020cce86f2559c12523c3e363 (
plain)
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
|
(.module:
[lux #*
[control
["M" monad (#+ do Monad)]
["&" continuation]]
[data
["." number]
[collection
["." list]]]
["r" math/random]]
lux/test)
(context: "Continuations"
(<| (times 100)
(do @
[sample r.nat
#let [(^open "&/.") &.Apply<Cont>
(^open "&/.") &.Monad<Cont>]
elems (r.list 3 r.nat)]
($_ seq
(test "Can run continuations to compute their values."
(n/= sample (&.run (&/wrap sample))))
(test "Can use functor."
(n/= (inc sample) (&.run (&/map inc (&/wrap sample)))))
(test "Can use apply."
(n/= (inc sample) (&.run (&/apply (&/wrap inc) (&/wrap sample)))))
(test "Can use monad."
(n/= (inc sample) (&.run (do &.Monad<Cont>
[func (wrap inc)
arg (wrap sample)]
(wrap (func arg))))))
(test "Can use the current-continuation as a escape hatch."
(n/= (n/* 2 sample)
(&.run (do &.Monad<Cont>
[value (&.call/cc
(function (_ k)
(do @
[temp (k sample)]
## If this code where to run,
## the output would be
## (n/* 4 sample)
(k temp))))]
(wrap (n/* 2 value))))))
(test "Can use the current-continuation to build a time machine."
(n/= (n/+ 100 sample)
(&.run (do &.Monad<Cont>
[[restart [output idx]] (&.portal [sample 0])]
(if (n/< 10 idx)
(restart [(n/+ 10 output) (inc idx)])
(wrap output))))))
(test "Can use delimited continuations with shifting."
(let [(^open "&/.") &.Monad<Cont>
(^open "L/.") (list.Equivalence<List> number.Equivalence<Nat>)
visit (: (-> (List Nat)
(&.Cont (List Nat) (List Nat)))
(function (visit xs)
(case xs
#.Nil
(&/wrap #.Nil)
(#.Cons x xs')
(do &.Monad<Cont>
[output (&.shift (function (_ k)
(do @
[tail (k xs')]
(wrap (#.Cons x tail)))))]
(visit output)))))]
(L/= elems
(&.run (&.reset (visit elems))))
))
))))
|