aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/control/monad.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/control/monad.lux')
-rw-r--r--stdlib/source/lux/control/monad.lux73
1 files changed, 43 insertions, 30 deletions
diff --git a/stdlib/source/lux/control/monad.lux b/stdlib/source/lux/control/monad.lux
index f9f7cab96..856509baa 100644
--- a/stdlib/source/lux/control/monad.lux
+++ b/stdlib/source/lux/control/monad.lux
@@ -4,7 +4,7 @@
(applicative #as A)))
## [Utils]
-(def: (L/fold f init xs)
+(def: (list/fold f init xs)
(All [a b]
(-> (-> b a a) a (List b) a))
(case xs
@@ -12,14 +12,25 @@
init
(#;Cons x xs')
- (L/fold f (f x init) xs')))
+ (list/fold f (f x init) xs')))
+
+(def: (list/size xs)
+ (All [a] (-> (List a) Nat))
+ (loop [counter +0
+ xs xs]
+ (case xs
+ #;Nil
+ counter
+
+ (#;Cons _ xs')
+ (recur (n.inc counter) xs'))))
(def: (reverse xs)
(All [a]
(-> (List a) (List a)))
- (L/fold (function [head tail] (#;Cons head tail))
- #;Nil
- xs))
+ (list/fold (function [head tail] (#;Cons head tail))
+ #;Nil
+ xs))
(def: (as-pairs xs)
(All [a] (-> (List a) (List [a a])))
@@ -49,33 +60,35 @@
(wrap (f3 z))))}
(case tokens
(#;Cons monad (#;Cons [_ (#;Tuple bindings)] (#;Cons body #;Nil)))
- (let [g!map (: Code [_cursor (#;Symbol ["" " map "])])
- g!join (: Code [_cursor (#;Symbol ["" " join "])])
- g!apply (: Code [_cursor (#;Symbol ["" " apply "])])
- body' (L/fold (: (-> [Code Code] Code Code)
- (function [binding body']
- (let [[var value] binding]
- (case var
- [_ (#;Tag ["" "let"])]
- (` (let (~ value) (~ body')))
-
- _
- (` (|> (~ value) ((~ g!map) (function [(~ var)] (~ body'))) (~ g!join)))
- ))))
- body
- (reverse (as-pairs bindings)))]
- (#;Right [state (#;Cons (` ("lux case" (~ monad)
- (~' @)
- ("lux case" (~' @)
- {#applicative {#A;functor {#F;map (~ g!map)}
- #A;wrap (~' wrap)
- #A;apply (~ g!apply)}
- #join (~ g!join)}
- (~ body'))))
- #;Nil)]))
+ (if (|> bindings list/size (n.% +2) (n.= +0))
+ (let [g!map (: Code [_cursor (#;Symbol ["" " map "])])
+ g!join (: Code [_cursor (#;Symbol ["" " join "])])
+ g!apply (: Code [_cursor (#;Symbol ["" " apply "])])
+ body' (list/fold (: (-> [Code Code] Code Code)
+ (function [binding body']
+ (let [[var value] binding]
+ (case var
+ [_ (#;Tag ["" "let"])]
+ (` (let (~ value) (~ body')))
+
+ _
+ (` (|> (~ value) ((~ g!map) (function [(~ var)] (~ body'))) (~ g!join)))
+ ))))
+ body
+ (reverse (as-pairs bindings)))]
+ (#;Right [state (#;Cons (` ("lux case" (~ monad)
+ (~' @)
+ ("lux case" (~' @)
+ {#applicative {#A;functor {#F;map (~ g!map)}
+ #A;wrap (~' wrap)
+ #A;apply (~ g!apply)}
+ #join (~ g!join)}
+ (~ body'))))
+ #;Nil)]))
+ (#;Left "'do' bindings must have an even number of parts."))
_
- (#;Left "Wrong syntax for do")))
+ (#;Left "Wrong syntax for 'do'")))
## [Functions]
(def: #export (seq monad xs)