diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/library/lux/data/lazy.lux | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/data/lazy.lux b/stdlib/source/library/lux/data/lazy.lux new file mode 100644 index 000000000..c9a6ae18c --- /dev/null +++ b/stdlib/source/library/lux/data/lazy.lux @@ -0,0 +1,68 @@ +(.module: + [library + [lux #* + [abstract + [functor (#+ Functor)] + [apply (#+ Apply)] + [monad (#+ Monad do)] + [equivalence (#+ Equivalence)]] + [control + ["." io] + [parser + ["s" code]] + [concurrency + ["." atom]]] + [macro (#+ with_gensyms) + [syntax (#+ syntax:)]] + [type + abstract]]]) + +(abstract: #export (Lazy a) + (-> [] a) + + (def: (freeze' generator) + (All [a] (-> (-> [] a) (Lazy a))) + (let [cache (atom.atom #.None)] + (:abstraction (function (_ _) + (case (io.run (atom.read cache)) + (#.Some value) + value + + _ + (let [value (generator [])] + (exec (io.run (atom.compare_and_swap _ (#.Some value) cache)) + value))))))) + + (def: #export (thaw l_value) + (All [a] (-> (Lazy a) a)) + ((:representation l_value) []))) + +(syntax: #export (freeze expr) + (with_gensyms [g!_] + (wrap (list (` ((~! freeze') (function ((~ g!_) (~ g!_)) (~ expr)))))))) + +(implementation: #export (equivalence (^open "_\.")) + (All [a] (-> (Equivalence a) (Equivalence (Lazy a)))) + + (def: (= left right) + (_\= (..thaw left) (..thaw right)))) + +(implementation: #export functor + (Functor Lazy) + + (def: (map f fa) + (freeze (f (thaw fa))))) + +(implementation: #export apply + (Apply Lazy) + + (def: &functor ..functor) + (def: (apply ff fa) + (freeze ((thaw ff) (thaw fa))))) + +(implementation: #export monad + (Monad Lazy) + + (def: &functor ..functor) + (def: wrap (|>> freeze)) + (def: join thaw)) |