aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/function/trampoline.lux
blob: d12bc5a79c4035434aa21a37353fc0d3f5f852c6 (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
54
55
56
57
(.require
 [library
  [lux (.except)
   [abstract
    [functor (.only Functor)]
    [monad (.only Monad)]]
   [meta
    ["[0]" code
     ["?[1]" \\parser]]
    [macro (.only with_symbols)
     [syntax (.only syntax)]]]]])

(type .public (Trampoline a)
  (Variant
   {#Return a}
   {#Jump (-> Any (Trampoline a))}))

(def .public return
  (All (_ value)
    (-> value
        (Trampoline value)))
  (|>> {#Return}))

(def .public jump
  (syntax (_ [thunk ?code.any])
    (with_symbols [g!_]
      (in (list (` {#Jump (function ((, g!_) (, g!_))
                            (, thunk))}))))))

(def .public (result it)
  (All (_ value)
    (-> (Trampoline value)
        value))
  (when it
    {#Return it}
    it
    
    {#Jump next}
    (result (next []))))

(def .public functor
  (Functor Trampoline)
  (implementation
   (def (each $ it)
     (when it
       {#Return it}
       {#Return ($ it)}
       
       {#Jump next}
       (each $ (next []))))))

(def .public monad
  (Monad Trampoline)
  (implementation
   (def functor ..functor)
   (def in ..return)
   (def conjoint ..result)))