blob: 5ed443040229514f312f7b827680ee6d756fb4c9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
(;module:
lux
["F" ../functor]
[lux/data/coll/list #* "" Fold<List>])
## [Signatures]
(sig: #export (CoMonad w)
{#;doc "CoMonads are the opposite/complement to monads.
CoMonadic structures are often infinite in size and built upon lazily-evaluated functions."}
(: (F;Functor w)
functor)
(: (All [a]
(-> (w a) a))
unwrap)
(: (All [a]
(-> (w a) (w (w a))))
split))
## [Syntax]
(def: _cursor Cursor ["" +0 +0])
(macro: #export (be tokens state)
{#;doc (doc "A co-monadic parallel to the \"do\" macro."
(let [square (lambda [n] (i.* n n))]
(be CoMonad<Stream>
[inputs (iterate i.inc 2)]
(square (head inputs)))))}
(case tokens
(#;Cons comonad (#;Cons [_ (#;TupleS bindings)] (#;Cons body #;Nil)))
(let [g!map (: AST [_cursor (#;SymbolS ["" " map "])])
g!split (: AST [_cursor (#;SymbolS ["" " split "])])
body' (fold (: (-> [AST AST] AST AST)
(lambda [binding body']
(let [[var value] binding]
(case var
[_ (#;TagS ["" "let"])]
(` (let (~ value) (~ body')))
_
(` (|> (~ value) (~ g!split) ((~ g!map) (lambda [(~ var)] (~ body')))))
))))
body
(reverse (as-pairs bindings)))]
(#;Right [state (#;Cons (` (;_lux_case (~ comonad)
(~' @)
(;_lux_case (~' @)
{#functor {#F;map (~ g!map)} #unwrap (~' unwrap) #split (~ g!split)}
(~ body'))))
#;Nil)]))
_
(#;Left "Wrong syntax for be")))
|