aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/control/continuation.lux
blob: cdabfb8d06c53165776f8040fa679271dad035a4 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(.module:
  [library
   [lux "*"
    ["_" test {"+" [Test]}]
    [abstract
     [monad {"+" [do]}]
     [\\specification
      ["$[0]" functor {"+" [Injection Comparison]}]
      ["$[0]" apply]
      ["$[0]" monad]]]
    [data
     [collection
      ["[0]" list]]]
    [math
     ["[0]" random]
     [number
      ["n" nat]]]]]
  [\\library
   ["[0]" /]])

(def: injection
  (All (_ o) (Injection (All (_ i) (/.Cont i o))))
  (|>> /.pending))

(def: comparison
  (Comparison /.Cont)
  (function (_ == left right)
    (== (/.result left) (/.result right))))

(def: .public test
  Test
  (<| (_.covering /._)
      (do random.monad
        [sample random.nat
         .let [(^open "_\[0]") /.apply
               (^open "_\[0]") /.monad]
         elems (random.list 3 random.nat)])
      (_.for [/.Cont])
      ($_ _.and
          (_.for [/.functor]
                 ($functor.spec ..injection ..comparison /.functor))
          (_.for [/.apply]
                 ($apply.spec ..injection ..comparison /.apply))
          (_.for [/.monad]
                 ($monad.spec ..injection ..comparison /.monad))

          (_.cover [/.result]
                   (n.= sample (/.result (_\in sample))))
          (_.cover [/.with_current]
                   (n.= (n.* 2 sample)
                        (/.result (do [! /.monad]
                                    [value (/.with_current
                                             (function (_ k)
                                               (do !
                                                 [temp (k sample)]
                                                 ... If this code where to run,
                                                 ... the output would be
                                                 ... (n.* 4 sample)
                                                 (k temp))))]
                                    (in (n.* 2 value))))))
          (_.cover [/.portal]
                   (n.= (n.+ 100 sample)
                        (/.result (do /.monad
                                    [[restart [output idx]] (/.portal [sample 0])]
                                    (if (n.< 10 idx)
                                      (restart [(n.+ 10 output) (++ idx)])
                                      (in output))))))
          (_.cover [/.shift /.reset]
                   (let [(^open "_\[0]") /.monad
                         (^open "list\[0]") (list.equivalence n.equivalence)
                         visit (: (-> (List Nat)
                                      (/.Cont (List Nat) (List Nat)))
                                  (function (visit xs)
                                    (case xs
                                      {.#End}
                                      (_\in {.#End})

                                      {.#Item x xs'}
                                      (do [! /.monad]
                                        [output (/.shift (function (_ k)
                                                           (do !
                                                             [tail (k xs')]
                                                             (in {.#Item x tail}))))]
                                        (visit output)))))]
                     (list\= elems
                             (/.result (/.reset (visit elems))))))
          (_.cover [/.continued]
                   (/.continued (same? sample)
                                (: (/.Cont Nat Bit)
                                   (function (_ next)
                                     (next sample)))))
          (_.cover [/.pending]
                   (/.continued (same? sample)
                                (: (/.Cont Nat Bit)
                                   (/.pending sample))))
          )))