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