diff options
Diffstat (limited to 'stdlib/source/lux/control/reader.lux')
-rw-r--r-- | stdlib/source/lux/control/reader.lux | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/stdlib/source/lux/control/reader.lux b/stdlib/source/lux/control/reader.lux new file mode 100644 index 000000000..598bfc670 --- /dev/null +++ b/stdlib/source/lux/control/reader.lux @@ -0,0 +1,63 @@ +(;module: + lux + (lux (control functor + applicative + ["M" monad #*]))) + +## [Types] +(type: #export (Reader r a) + {#;doc "Computations that have access to some environmental value."} + (-> r a)) + +## [Structures] +(struct: #export Functor<Reader> (All [r] (Functor (Reader r))) + (def: (map f fa) + (function [env] + (f (fa env))))) + +(struct: #export Applicative<Reader> (All [r] (Applicative (Reader r))) + (def: functor Functor<Reader>) + + (def: (wrap x) + (function [env] x)) + + (def: (apply ff fa) + (function [env] + ((ff env) (fa env))))) + +(struct: #export Monad<Reader> (All [r] (Monad (Reader r))) + (def: applicative Applicative<Reader>) + + (def: (join mma) + (function [env] + (mma env env)))) + +## [Values] +(def: #export ask + {#;doc "Get the environment."} + (All [r] (Reader r r)) + (function [env] env)) + +(def: #export (local change reader-proc) + {#;doc "Run computation with a locally-modified environment."} + (All [r a] (-> (-> r r) (Reader r a) (Reader r a))) + (|>. change reader-proc)) + +(def: #export (run env reader-proc) + (All [r a] (-> r (Reader r a) a)) + (reader-proc env)) + +(struct: #export (ReaderT Monad<M>) + {#;doc "Monad transformer for Reader."} + (All [M] (-> (Monad M) (All [e] (Monad (All [a] (Reader e (M a))))))) + (def: applicative (compA Applicative<Reader> (get@ #M;applicative Monad<M>))) + (def: (join eMeMa) + (function [env] + (do Monad<M> + [eMa (run env eMeMa)] + (run env eMa))))) + +(def: #export lift-reader + {#;doc "Lift monadic values to the Reader wrapper."} + (All [M e a] (-> (M a) (Reader e (M a)))) + (:: Monad<Reader> wrap)) |