diff options
Diffstat (limited to 'stdlib/source/lux/function/cont.lux')
-rw-r--r-- | stdlib/source/lux/function/cont.lux | 69 |
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)) |