aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/function/cont.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/function/cont.lux')
-rw-r--r--stdlib/source/lux/function/cont.lux69
1 files changed, 69 insertions, 0 deletions
diff --git a/stdlib/source/lux/function/cont.lux b/stdlib/source/lux/function/cont.lux
new file mode 100644
index 000000000..f6330cbe4
--- /dev/null
+++ b/stdlib/source/lux/function/cont.lux
@@ -0,0 +1,69 @@
+(;module:
+ lux
+ (lux (macro [ast])
+ (control functor
+ applicative
+ monad)
+ (data (coll list))
+ function))
+
+## [Types]
+(type: #export (Cont a)
+ {#;doc "Delimited continuations."}
+ (All [b]
+ (-> (-> a b) b)))
+
+## [Syntax]
+(macro: #export (@lazy tokens state)
+ {#;doc (doc "Delays the evaluation of an expression, by wrapping it in a continuation 'thunk'."
+ (@lazy (some-computation some-input)))}
+ (case tokens
+ (^ (list value))
+ (let [blank (ast;symbol ["" ""])]
+ (#;Right [state (list (` (;lambda [(~ blank)] ((~ blank) (~ value)))))]))
+
+ _
+ (#;Left "Wrong syntax for @lazy")))
+
+## [Functions]
+(def: #export (call/cc f)
+ {#;doc "Call with current continuation."}
+ (All [a b c]
+ (-> (-> (-> a (Cont b c))
+ (Cont a c))
+ (Cont a c)))
+ (lambda [k]
+ (f (lambda [a _]
+ (k a))
+ k)))
+
+(def: #export (continue f thunk)
+ {#;doc "Forces a continuation thunk to be evaluated."}
+ (All [i o]
+ (-> (-> i o) (Cont i o) o))
+ (thunk f))
+
+(def: #export (run thunk)
+ {#;doc "Forces a continuation thunk to be evaluated."}
+ (All [a]
+ (-> (Cont a) a))
+ (continue id thunk))
+
+## [Structs]
+(struct: #export _ (Functor Cont)
+ (def: (map f ma)
+ (lambda [k] (ma (. k f)))))
+
+(struct: #export _ (Applicative Cont)
+ (def: functor Functor<Cont>)
+
+ (def: (wrap a)
+ (@lazy a))
+
+ (def: (apply ff fa)
+ (@lazy ((run ff) (run fa)))))
+
+(struct: #export _ (Monad Cont)
+ (def: applicative Applicative<Cont>)
+
+ (def: join run))