aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/function/trampoline.lux
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/library/lux/control/function/trampoline.lux57
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)))