(.module: [lux #* [abstract [functor (#+ Functor)] [apply (#+ Apply)] [monad (#+ Monad do)] [equivalence (#+ Equivalence)]] [control ["." io] [parser ["s" code]] [concurrency ["." atom]]] [meta (#+ with-gensyms)] [macro [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)))))))) (structure: #export (equivalence (^open "_@.")) (All [a] (-> (Equivalence a) (Equivalence (Lazy a)))) (def: (= left right) (_@= (..thaw left) (..thaw right)))) (structure: #export functor (Functor Lazy) (def: (map f fa) (freeze (f (thaw fa))))) (structure: #export apply (Apply Lazy) (def: &functor ..functor) (def: (apply ff fa) (freeze ((thaw ff) (thaw fa))))) (structure: #export monad (Monad Lazy) (def: &functor ..functor) (def: wrap (|>> freeze)) (def: join thaw))