aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/concurrency/task.lux
blob: 6f880ef790e3405c01b72efcf4493a854d843409 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
(;module:
  lux
  (lux (data ["R" result])
       (control functor
                applicative
                monad
                ["ex" exception #+ Exception])
       (concurrency ["P" promise])
       [macro]
       (macro ["s" syntax #+ syntax: Syntax])
       ))

(type: #export (Task a)
  (P;Promise (R;Result a)))

(def: #export (fail error)
  (All [a] (-> Text (Task a)))
  (:: P;Applicative<Promise> wrap (#R;Error error)))

(def: #export (throw exception message)
  (All [a] (-> Exception Text (Task a)))
  (fail (exception message)))

(def: #export (return value)
  (All [a] (-> a (Task a)))
  (:: P;Applicative<Promise> wrap (#R;Success value)))

(def: #export (try computation)
  (All [a] (-> (Task a) (Task (R;Result a))))
  (:: P;Functor<Promise> map (|>. #R;Success) computation))

(struct: #export _ (Functor Task)
  (def: (map f fa)
    (:: P;Functor<Promise> map
        (function [fa']
          (case fa'
            (#R;Error error)
            (#R;Error error)

            (#R;Success a)
            (#R;Success (f a))))
        fa)))

(struct: #export _ (Applicative Task)
  (def: functor Functor<Task>)

  (def: wrap return)

  (def: (apply ff fa)
    (do P;Monad<Promise>
      [ff' ff
       fa' fa]
      (wrap (do R;Monad<Result>
              [f ff'
               a fa']
              (wrap (f a)))))))

(struct: #export _ (Monad Task)
  (def: applicative Applicative<Task>)

  (def: (join mma)
    (do P;Monad<Promise>
      [mma' mma]
      (case mma'
        (#R;Error error)
        (wrap (#R;Error error))

        (#R;Success ma)
        ma))))

(syntax: #export (task [type s;any])
  {#;doc (doc "Makes an uninitialized Task (in this example, of Unit)."
              (task Unit))}
  (wrap (list (` (: (;;Task (~ type))
                    (P;promise' #;None))))))