diff options
Diffstat (limited to 'stdlib/source/test/lux/control/continuation.lux')
-rw-r--r-- | stdlib/source/test/lux/control/continuation.lux | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/stdlib/source/test/lux/control/continuation.lux b/stdlib/source/test/lux/control/continuation.lux new file mode 100644 index 000000000..0dbbe7dc5 --- /dev/null +++ b/stdlib/source/test/lux/control/continuation.lux @@ -0,0 +1,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 + (^open "&/.") &.monad] + 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 + [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 + [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 + [[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 + (^open "L/.") (list.equivalence number.equivalence) + visit (: (-> (List Nat) + (&.Cont (List Nat) (List Nat))) + (function (visit xs) + (case xs + #.Nil + (&/wrap #.Nil) + + (#.Cons x xs') + (do &.monad + [output (&.shift (function (_ k) + (do @ + [tail (k xs')] + (wrap (#.Cons x tail)))))] + (visit output)))))] + (L/= elems + (&.run (&.reset (visit elems)))) + )) + )))) |