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