diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/library/lux/control/function/trampoline.lux | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/control/function/trampoline.lux b/stdlib/source/library/lux/control/function/trampoline.lux new file mode 100644 index 000000000..d12bc5a79 --- /dev/null +++ b/stdlib/source/library/lux/control/function/trampoline.lux @@ -0,0 +1,57 @@ +(.require + [library + [lux (.except) + [abstract + [functor (.only Functor)] + [monad (.only Monad)]] + [meta + ["[0]" code + ["?[1]" \\parser]] + [macro (.only with_symbols) + [syntax (.only syntax)]]]]]) + +(type .public (Trampoline a) + (Variant + {#Return a} + {#Jump (-> Any (Trampoline a))})) + +(def .public return + (All (_ value) + (-> value + (Trampoline value))) + (|>> {#Return})) + +(def .public jump + (syntax (_ [thunk ?code.any]) + (with_symbols [g!_] + (in (list (` {#Jump (function ((, g!_) (, g!_)) + (, thunk))})))))) + +(def .public (result it) + (All (_ value) + (-> (Trampoline value) + value)) + (when it + {#Return it} + it + + {#Jump next} + (result (next [])))) + +(def .public functor + (Functor Trampoline) + (implementation + (def (each $ it) + (when it + {#Return it} + {#Return ($ it)} + + {#Jump next} + (each $ (next [])))))) + +(def .public monad + (Monad Trampoline) + (implementation + (def functor ..functor) + (def in ..return) + (def conjoint ..result))) |