aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/concurrency/task.lux
blob: 66cc12ff3240b229188be5cf4d3d76013f214e9a (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
76
77
78
79
80
(.module:
  lux
  (lux (data ["E" error])
       (control ["F" functor]
                ["A" apply]
                monad
                ["ex" exception #+ Exception])
       (concurrency ["P" promise])
       [macro]
       (macro ["s" syntax #+ syntax: Syntax])
       ))

(type: #export (Task a)
  (P.Promise (E.Error a)))

(def: #export (fail error)
  (All [a] (-> Text (Task a)))
  (:: P.Monad<Promise> wrap (#E.Error error)))

(def: #export (throw exception message)
  (All [e a] (-> (Exception e) e (Task a)))
  (:: P.Monad<Promise> wrap
      (ex.throw exception message)))

(def: #export (return value)
  (All [a] (-> a (Task a)))
  (:: P.Monad<Promise> wrap (#E.Success value)))

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

(struct: #export _ (F.Functor Task)
  (def: (map f fa)
    (:: P.Functor<Promise> map
        (function (_ fa')
          (case fa'
            (#E.Error error)
            (#E.Error error)

            (#E.Success a)
            (#E.Success (f a))))
        fa)))

(struct: #export _ (A.Apply Task)
  (def: functor Functor<Task>)

  (def: (apply ff fa)
    (do P.Monad<Promise>
      [ff' ff
       fa' fa]
      (wrap (do E.Monad<Error>
              [f ff'
               a fa']
              (wrap (f a)))))))

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

  (def: wrap return)

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

        (#E.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))))))

(def: #export (from-promise promise)
  (All [a] (-> (P.Promise a) (Task a)))
  (:: P.Functor<Promise> map (|>> #E.Success) promise))