aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/control/effect.lux57
1 files changed, 32 insertions, 25 deletions
diff --git a/stdlib/source/lux/control/effect.lux b/stdlib/source/lux/control/effect.lux
index 297fc3bdb..6643acd26 100644
--- a/stdlib/source/lux/control/effect.lux
+++ b/stdlib/source/lux/control/effect.lux
@@ -14,6 +14,7 @@
error
[ident "Ident/" Eq<Ident>])
[compiler]
+ [macro]
(macro [ast]
["s" syntax #+ syntax: Syntax]
(syntax [common]))
@@ -25,7 +26,9 @@
(#Effect (F (Eff F a))))
(sig: #export (Handler E M)
- (: (All [a] (-> (Eff E a) (M a)))
+ (: (Monad M)
+ monad)
+ (: (All [a] (-> (E a) (M a)))
handle))
## [Values]
@@ -102,17 +105,13 @@
(Handler L M) (Handler R M)
(Handler (|@ L R) M)))
(struct
- (def: (handle el|r)
- (case el|r
- (#Pure x)
- (:: Monad<M> wrap x)
-
- (#Effect l|r)
- (case l|r
- (#;Left l) (:: left handle (#Effect l))
- (#;Right r) (:: right handle (#Effect r))
- ))
- )))
+ (def: monad Monad<M>)
+
+ (def: (handle l|r)
+ (case l|r
+ (#;Left l) (:: left handle l)
+ (#;Right r) (:: right handle r)
+ ))))
## [Syntax]
(syntax: #export (|E [effects (s;many s;any)])
@@ -190,8 +189,8 @@
(type: Translation
{#effect Ident
- #base AST
- #monad AST})
+ #target-type AST
+ #target-monad AST})
(def: translation^
(Syntax Translation)
@@ -210,6 +209,7 @@
g!input (compiler;gensym "g!input")
g!cont (compiler;gensym "g!cont")
g!value (compiler;gensym "value")
+ g!wrap (compiler;gensym "wrap")
#let [g!cases (|> defs
(List/map (lambda [def]
(let [g!tag (ast;tag [e-module (get@ #common;def-name def)])
@@ -229,24 +229,31 @@
(` ((~ eff-calc) (~@ g!args))))]
(list (` ((~ g!tag) [(~@ g!args)] (~ g!cont)))
(` (do (~ target-monad)
- [(~ g!value) (~ invocation)]
- ((~' handle) ((~ g!cont) (~ g!value)))))
+ [(~' #let) [(~ g!wrap) (~' wrap)]
+ (~ g!value) (~ invocation)]
+ ((~ g!wrap) ((~ g!cont) (~ g!value)))))
))))
List/join)]]
(wrap (list (` (struct: (~@ (common;gen-export-level exp-lvl)) (~ (ast;symbol ["" name]))
(;;Handler (~ (ast;symbol effect)) (~ target-type))
+ (def: (~' monad) (~ target-monad))
+
(def: ((~' handle) (~ g!input))
(case (~ g!input)
- (#Pure (~ g!input))
- (:: (~ target-monad) (~' wrap) (~ g!input))
-
- (#Effect (~ g!input))
- (case (~ g!input)
- (~@ g!cases)))
+ (~@ g!cases))
)))))))
-(syntax: #export (with-handler handler body)
- (wrap (list (` (:: (~ handler) (~' handle) (~ body))))))
+(def: #export (with-handler handler body)
+ (All [E M a] (-> (Handler E M) (Eff E a) (M a)))
+ (case body
+ (#Pure value)
+ (:: handler wrap value)
+
+ (#Effect effect)
+ (do (get@ #monad handler)
+ [result (:: handler handle effect)]
+ (with-handler handler result))
+ ))
(def: (un-apply type-app)
(-> Type Type)
@@ -275,7 +282,7 @@
(do (Monad<Eff> (~ g!functor))
[(~@ bindings)
(~ g!output) (~ body)]
- ((~' wrap) (~ g!output)))))))))
+ (#;;Pure (~ g!output)))))))))
(def: (flatten-effect-stack stack)
(-> Type (List Type))