@@ -8,158 +8,181 @@ import TListK.::
8
8
9
9
package object quasi {
10
10
11
- type Quasi [S [_], A ] = quasiImpl.Quasi [ S , A ]
12
- type Concur [S [_], A ] = quasiImpl.Concur [S , A ]
13
- type Subseq [S [_], A ] = quasiImpl.Subseq [S , A ]
11
+ type Quasi [S [_], E , A ] = quasiImpl.Quasi [ S , E , A ]
12
+ type Concur [S [_], E , A ] = quasiImpl.Concur [S , E , A ]
13
+ type Subseq [S [_], E , A ] = quasiImpl.Subseq [S , E , A ]
14
14
15
- implicit final class QuasiOps [S [_], A ](val quasi : Quasi [S , A ]) extends AnyVal {
16
- def concur : Concur [S , A ] = quasiImpl.toConcur(quasi)
17
- def subseq : Subseq [S , A ] = quasiImpl.toSubseq(quasi)
15
+ implicit final class QuasiOps [S [_], E , A ](val quasi : Quasi [S , E , A ]) extends AnyVal {
16
+ def concur : Concur [S , E , A ] = quasiImpl.toConcur(quasi)
17
+ def subseq : Subseq [S , E , A ] = quasiImpl.toSubseq(quasi)
18
18
}
19
19
20
- final implicit class ConcurOps [S [_], A ](val concur : Concur [S , A ]) extends AnyVal {
21
- def quasi : Quasi [S , A ] = quasiImpl.fromConcur(concur)
22
- def subseq : Subseq [S , A ] = quasi.subseq
20
+ final implicit class ConcurOps [S [_], E , A ](val concur : Concur [S , E , A ]) extends AnyVal {
21
+ def quasi : Quasi [S , E , A ] = quasiImpl.fromConcur(concur)
22
+ def subseq : Subseq [S , E , A ] = quasi.subseq
23
23
24
- def ap [B ](f : Concur [S , A => B ]): Concur [S , B ] =
24
+ def ap [B ](f : Concur [S , E , A => B ]): Concur [S , E , B ] =
25
25
quasiImpl.ap(f.quasi)(concur.quasi).concur
26
26
27
- def map [B ](f : A => B ): Concur [S , B ] = ap(Quasi .pure(f).concur)
27
+ def map [B ](f : A => B ): Concur [S , E , B ] = ap(Quasi .pure(f).concur)
28
28
}
29
29
30
- final implicit class SubseqOps [S [_], A ](val subseq : Subseq [S , A ]) extends AnyVal {
31
- def quasi : Quasi [S , A ] = quasiImpl.fromSubseq(subseq)
32
- def concur : Concur [S , A ] = quasi.concur
30
+ final implicit class SubseqOps [S [_], E , A ](val subseq : Subseq [S , E , A ]) extends AnyVal {
31
+ def quasi : Quasi [S , E , A ] = quasiImpl.fromSubseq(subseq)
32
+ def concur : Concur [S , E , A ] = quasi.concur
33
33
34
- def map [B ](f : A => B ): Subseq [S , B ] =
34
+ def map [B ](f : A => B ): Subseq [S , E , B ] =
35
35
flatMap(a => Quasi .pure(f(a)).subseq)
36
36
37
- def flatMap [B ](f : A => Subseq [S , B ]): Subseq [S , B ] =
37
+ def flatMap [B ](f : A => Subseq [S , E , B ]): Subseq [S , E , B ] =
38
38
quasiImpl.flatMap(subseq.quasi)(f.andThen(_.quasi)).subseq
39
39
}
40
40
41
- implicit def subseqMonad [S [_]]: Monad [Subseq [S , ? ] ] = new Monad [Subseq [S , ? ] ] {
42
- def pure [A ](a : A ): Subseq [S , A ] = Quasi .pure(a).subseq
43
- def flatMap [A , B ](fa : Subseq [S , A ])(f : A => Subseq [S , B ]): Subseq [S , B ] =
41
+ implicit def subseqMonadError [S [_], E ]: MonadError [Subseq [S , E , ? ], E ] = new MonadError [Subseq [S , E , ? ], E ] {
42
+ def pure [A ](a : A ): Subseq [S , E , A ] = Quasi .pure(a).subseq
43
+ def flatMap [A , B ](fa : Subseq [S , E , A ])(f : A => Subseq [S , E , B ]): Subseq [S , E , B ] =
44
44
fa.flatMap(f)
45
45
46
- def tailRecM [A , B ](a : A )(f : A => Subseq [S , Either [A , B ]]): Subseq [S , B ] = ???
46
+ def tailRecM [A , B ](a : A )(f : A => Subseq [S , E , Either [A , B ]]): Subseq [S , E , B ] = ???
47
+
48
+ def handleErrorWith [A ](fa : Subseq [S , E , A ])(f : E => Subseq [S , E , A ]): Subseq [S , E , A ] =
49
+ quasiImpl.guard(fa.quasi, f.andThen(_.quasi)).subseq
50
+
51
+ def raiseError [A ](e : E ): Subseq [S , E , A ] =
52
+ quasiImpl.raise(e).subseq
47
53
}
48
54
49
- implicit def concurApplicative [S [_]]: Applicative [Concur [S , ? ]] = new Applicative [Concur [S , ? ]] {
50
- def pure [A ](a : A ): Concur [S , A ] = Quasi .pure(a).concur
51
- def ap [A , B ](ff : Concur [S , A => B ])(fa : Concur [S , A ]): Concur [S , B ] =
55
+ implicit def concurApplicative [S [_], E ]: Applicative [Concur [S , E , ? ]] = new Applicative [Concur [S , E , ? ]] {
56
+ def pure [A ](a : A ): Concur [S , E , A ] = Quasi .pure(a).concur
57
+ def ap [A , B ](ff : Concur [S , E , A => B ])(fa : Concur [S , E , A ]): Concur [S , E , B ] =
52
58
fa.ap(ff)
53
59
}
54
60
55
- implicit def subseqConcurParallel [S [_]]: Parallel [Subseq [S , ? ], Concur [S , ? ]] =
56
- new Parallel [Subseq [S , ? ], Concur [S , ? ]] {
57
- val parallel : Subseq [S , ? ] ~> Concur [S , ? ] =
58
- λ[Subseq [S , ? ] ~> Concur [S , ? ]](_.quasi.concur)
59
- val sequential : Concur [S , ? ] ~> Subseq [S , ? ] =
60
- λ[Concur [S , ? ] ~> Subseq [S , ? ]](_.quasi.subseq)
61
- val applicative : Applicative [Concur [S , ? ]] = Applicative [Concur [S , ? ]]
62
- val monad : Monad [Subseq [S , ? ]] = Monad [Subseq [S , ? ]]
61
+ implicit def subseqConcurParallel [S [_], E ]: Parallel [Subseq [S , E , ? ], Concur [S , E , ? ]] =
62
+ new Parallel [Subseq [S , E , ? ], Concur [S , E , ? ]] {
63
+ val parallel : Subseq [S , E , ? ] ~> Concur [S , E , ? ] =
64
+ λ[Subseq [S , E , ? ] ~> Concur [S , E , ? ]](_.quasi.concur)
65
+ val sequential : Concur [S , E , ? ] ~> Subseq [S , E , ? ] =
66
+ λ[Concur [S , E , ? ] ~> Subseq [S , E , ? ]](_.quasi.subseq)
67
+ val applicative : Applicative [Concur [S , E , ? ]] = Applicative [Concur [S , E , ? ]]
68
+ val monad : Monad [Subseq [S , E , ? ]] = Monad [Subseq [S , E , ? ]]
63
69
}
64
70
65
71
object Quasi {
66
72
67
- def pure [S [_], A ](a : A ): Quasi [S , A ] = quasiImpl.pure(a)
68
- def liftF [S [_], A ](value : S [A ]): Quasi [S , A ] = quasiImpl.suspend(value)
69
-
70
- def toConcur [S [_]]: Quasi [S , ? ] ~> Concur [S , ? ] =
71
- λ[Quasi [S , ? ] ~> Concur [S , ? ]](_.concur)
72
-
73
- def toSubseq [S [_]]: Quasi [S , ? ] ~> Subseq [S , ? ] =
74
- λ[Quasi [S , ? ] ~> Subseq [S , ? ]](_.subseq)
75
-
76
- def foldMap [S [_], M [_], A ](quasi : Quasi [S , A ])(f : S ~> M )(implicit M : Parallel [M , M ]): M [A ] =
77
- quasiImpl.evaluator(f,
78
- M .parallel, M .sequential,
79
- M .monad, M .applicative)(quasi)
73
+ def pure [S [_], E , A ](a : A ): Quasi [S , E , A ] = quasiImpl.pure(a)
74
+ def liftF [S [_], E , A ](value : S [A ]): Quasi [S , E , A ] = quasiImpl.suspend(value)
75
+
76
+ def toConcur [S [_], E ]: Quasi [S , E , ? ] ~> Concur [S , E , ? ] =
77
+ λ[Quasi [S , E , ? ] ~> Concur [S , E , ? ]](_.concur)
78
+
79
+ def toSubseq [S [_], E ]: Quasi [S , E , ? ] ~> Subseq [S , E , ? ] =
80
+ λ[Quasi [S , E , ? ] ~> Subseq [S , E , ? ]](_.subseq)
81
+
82
+ def foldMap [S [_], Zm [_], Za [_], E , A ]
83
+ (quasi : Quasi [S , E , A ])(f : S ~> Zm )(implicit Z : Parallel [Zm , Za ], E : MonadError [Zm , E ]): Zm [A ] =
84
+ quasiImpl.evaluator(
85
+ f,
86
+ Z .parallel,
87
+ Z .sequential,
88
+ Z .monad,
89
+ Z .applicative,
90
+ λ[λ[α => (Zm [α], E => Zm [α])] ~> Zm ](n => E .handleErrorWith(n._1)(n._2)),
91
+ λ[λ[α => E ] ~> Zm ](E .raiseError(_)))(quasi)
80
92
}
81
93
82
94
private [quasi] sealed trait QuasiImpl {
83
- type Quasi [S [_], A ]
84
- type Concur [S [_], A ]
85
- type Subseq [S [_], A ]
86
-
87
- type Effects [S [_]] =
88
- Pure [S , ? ] ::
89
- Suspend [S , ? ] ::
90
- FlatMap [S , _, ? ] ::
91
- Ap [S , _, ? ] ::
92
- Raise [S , _, ? ] ::
93
- Handle [S , _, ? ] ::
95
+ type Quasi [S [_], E , A ]
96
+ type Concur [S [_], E , A ]
97
+ type Subseq [S [_], E , A ]
98
+
99
+ type Effects [S [_], E ] =
100
+ Pure [S , ? ] ::
101
+ Suspend [S , ? ] ::
102
+ FlatMap [S , E , _, ? ] ::
103
+ Ap [S , E , _, ? ] ::
104
+ Guard [S , E , ? ] ::
105
+ Raise [S , E , ? ] ::
94
106
TNilK
95
107
96
108
type Pure [S [_], A ] = A
97
109
type Suspend [S [_], A ] = S [A ]
98
- final case class FlatMap [S [_], A , B ](fa : Quasi [S , A ], f : A => Quasi [S , B ])
99
- final case class Ap [S [_], A , B ](ff : Quasi [S , A => B ], fa : Quasi [S , A ])
110
+ final case class FlatMap [S [_], E , A , B ](fa : Quasi [S , E , A ], f : A => Quasi [S , E , B ])
111
+ final case class Ap [S [_], E , A , B ](ff : Quasi [S , E , A => B ], fa : Quasi [S , E , A ])
112
+ final case class Guard [S [_], E , A ](fa : Quasi [S , E , A ], f : E => Quasi [S , E , A ])
100
113
type Raise [S [_], E , A ] = E
101
- final case class Handle [S [_], E , A ](fe : E => Quasi [S , A ])
102
- // type Handle[S[_], E, A] = E => Quasi[S, A]
103
114
104
- def toRaw [S [_], A ](quasi : Quasi [S , A ]): CopK [Effects [S ], A ]
105
- def fromRaw [S [_], A ](copK : CopK [Effects [S ], A ]): Quasi [S , A ]
115
+ def toRaw [S [_], E , A ](quasi : Quasi [S , E , A ]): CopK [Effects [S , E ], A ]
116
+ def fromRaw [S [_], E , A ](copK : CopK [Effects [S , E ], A ]): Quasi [S , E , A ]
106
117
107
- def toConcur [S [_], A ](quasi : Quasi [S , A ]): Concur [S , A ]
108
- def fromConcur [S [_], A ](subseq : Concur [S , A ]): Quasi [S , A ]
118
+ def toConcur [S [_], E , A ](quasi : Quasi [S , E , A ]): Concur [S , E , A ]
119
+ def fromConcur [S [_], E , A ](subseq : Concur [S , E , A ]): Quasi [S , E , A ]
109
120
110
- def toSubseq [S [_], A ](quasi : Quasi [S , A ]): Subseq [S , A ]
111
- def fromSubseq [S [_], A ](subseq : Subseq [S , A ]): Quasi [S , A ]
121
+ def toSubseq [S [_], E , A ](quasi : Quasi [S , E , A ]): Subseq [S , E , A ]
122
+ def fromSubseq [S [_], E , A ](subseq : Subseq [S , E , A ]): Quasi [S , E , A ]
112
123
113
- def pure [S [_], A ](a : A ): Quasi [S , A ]
114
- def suspend [S [_], A ](value : S [A ]): Quasi [S , A ]
115
- def flatMap [S [_], A , B ](fa : Quasi [S , A ])(f : A => Quasi [S , B ]): Quasi [S , B ]
116
- def ap [S [_], A , B ](ff : Quasi [S , A => B ])(fa : Quasi [S , A ]): Quasi [S , B ]
124
+ def pure [S [_], E , A ](a : A ): Quasi [S , E , A ]
125
+ def suspend [S [_], E , A ](value : S [A ]): Quasi [S , E , A ]
126
+ def flatMap [S [_], E , A , B ](fa : Quasi [S , E , A ])(f : A => Quasi [S , E , B ]): Quasi [S , E , B ]
127
+ def ap [S [_], E , A , B ](ff : Quasi [S , E , A => B ])(fa : Quasi [S , E , A ]): Quasi [S , E , B ]
128
+ def guard [S [_], E , A ](fa : Quasi [S , E , A ], f : E => Quasi [S , E , A ]): Quasi [S , E , A ]
129
+ def raise [S [_], E , A ](e : E ): Quasi [S , E , A ]
117
130
118
- type Evaluator [S [_], M [_]] = Quasi [S , ? ] ~> M
131
+ type Evaluator [S [_], M [_], E ] = Quasi [S , E , ? ] ~> M
119
132
120
- def evaluator [S [_], Zm [_], Za [_]](
133
+ def evaluator [S [_], Zm [_], Za [_], E ](
121
134
f : S ~> Zm ,
122
135
parallel : Zm ~> Za ,
123
136
sequential : Za ~> Zm ,
124
137
Zm : Monad [Zm ],
125
- Za : Applicative [Za ]
126
- ): Evaluator [S , Zm ]
138
+ Za : Applicative [Za ],
139
+ guard : λ[α => (Zm [α], E => Zm [α])] ~> Zm ,
140
+ raise : λ[α => E ] ~> Zm
141
+ ): Evaluator [S , Zm , E ]
127
142
}
128
143
129
144
private [quasi] val quasiImpl : QuasiImpl = new QuasiImpl {
130
- type Quasi [S [_], A ] = CopK [Effects [S ], A ]
131
- type Concur [S [_], A ] = CopK [Effects [S ], A ]
132
- type Subseq [S [_], A ] = CopK [Effects [S ], A ]
145
+ type Quasi [S [_], E , A ] = CopK [Effects [S , E ], A ]
146
+ type Concur [S [_], E , A ] = CopK [Effects [S , E ], A ]
147
+ type Subseq [S [_], E , A ] = CopK [Effects [S , E ], A ]
133
148
134
- def toRaw [S [_], A ](quasi : Quasi [S , A ]): CopK [Effects [S ], A ] = quasi
135
- def fromRaw [S [_], A ](copK : CopK [Effects [S ], A ]): Quasi [S , A ] = copK
149
+ def toRaw [S [_], E , A ](quasi : Quasi [S , E , A ]): CopK [Effects [S , E ], A ] = quasi
150
+ def fromRaw [S [_], E , A ](copK : CopK [Effects [S , E ], A ]): Quasi [S , E , A ] = copK
136
151
137
- def toConcur [S [_], A ](quasi : Quasi [S , A ]): Concur [S , A ] = quasi
138
- def fromConcur [S [_], A ](subseq : Concur [S , A ]): Quasi [S , A ] = subseq
152
+ def toConcur [S [_], E , A ](quasi : Quasi [S , E , A ]): Concur [S , E , A ] = quasi
153
+ def fromConcur [S [_], E , A ](subseq : Concur [S , E , A ]): Quasi [S , E , A ] = subseq
139
154
140
- def toSubseq [S [_], A ](quasi : Quasi [S , A ]): Subseq [S , A ] = quasi
141
- def fromSubseq [S [_], A ](subseq : Subseq [S , A ]): Quasi [S , A ] = subseq
155
+ def toSubseq [S [_], E , A ](quasi : Quasi [S , E , A ]): Subseq [S , E , A ] = quasi
156
+ def fromSubseq [S [_], E , A ](subseq : Subseq [S , E , A ]): Quasi [S , E , A ] = subseq
142
157
143
- def pure [S [_], A ](a : A ): Quasi [S , A ] =
144
- CopK .unsafeApply[Effects [S ], Pure [S , ? ], A ](0 , a)
158
+ def pure [S [_], E , A ](a : A ): Quasi [S , E , A ] =
159
+ CopK .unsafeApply[Effects [S , E ], Pure [S , ? ], A ](0 , a)
145
160
146
- def suspend [S [_], A ](value : S [A ]): Quasi [S , A ] =
147
- CopK .unsafeApply[Effects [S ], Suspend [S , ? ], A ](1 , value)
161
+ def suspend [S [_], E , A ](value : S [A ]): Quasi [S , E , A ] =
162
+ CopK .unsafeApply[Effects [S , E ], Suspend [S , ? ], A ](1 , value)
148
163
149
- def flatMap [S [_], A , B ](fa : Quasi [S , A ])(f : A => Quasi [S , B ]): Quasi [S , B ] =
150
- CopK .unsafeApply[Effects [S ], FlatMap [S , A , ? ], B ](2 , FlatMap [S , A , B ](fa, f))
164
+ def flatMap [S [_], E , A , B ](fa : Quasi [S , E , A ])(f : A => Quasi [S , E , B ]): Quasi [S , E , B ] =
165
+ CopK .unsafeApply[Effects [S , E ], FlatMap [S , E , A , ? ], B ](2 , FlatMap [S , E , A , B ](fa, f))
151
166
152
- def ap [S [_], A , B ](ff : Quasi [S , A => B ])(fa : Quasi [S , A ]): Quasi [S , B ] =
153
- CopK .unsafeApply[Effects [S ], Ap [S , A , ? ], B ](3 , Ap [S , A , B ](ff, fa))
167
+ def ap [S [_], E , A , B ](ff : Quasi [S , E , A => B ])(fa : Quasi [S , E , A ]): Quasi [S , E , B ] =
168
+ CopK .unsafeApply[Effects [S , E ], Ap [S , E , A , ? ], B ](3 , Ap [S , E , A , B ](ff, fa))
154
169
155
- def evaluator [S [_], Zm [_], Za [_]](
170
+ def guard [S [_], E , A ](fa : Quasi [S , E , A ], f : E => Quasi [S , E , A ]): Quasi [S , E , A ] =
171
+ CopK .unsafeApply[Effects [S , E ], Guard [S , E , ? ], A ](4 , Guard [S , E , A ](fa, f))
172
+
173
+ def raise [S [_], E , A ](e : E ): Quasi [S , E , A ] =
174
+ CopK .unsafeApply[Effects [S , E ], Raise [S , E , ? ], A ](5 , e)
175
+
176
+ def evaluator [S [_], Zm [_], Za [_], E ](
156
177
f : S ~> Zm ,
157
178
parallel : Zm ~> Za ,
158
179
sequential : Za ~> Zm ,
159
180
Zm : Monad [Zm ],
160
- Za : Applicative [Za ]
161
- ): Evaluator [S , Zm ] = new Evaluator [S , Zm ] {
162
- def apply [A ](quasi : Quasi [S , A ]): Zm [A ] =
181
+ Za : Applicative [Za ],
182
+ guard : λ[α => (Zm [α], E => Zm [α])] ~> Zm ,
183
+ raise : λ[α => E ] ~> Zm
184
+ ): Evaluator [S , Zm , E ] = new Evaluator [S , Zm , E ] {
185
+ def apply [A ](quasi : Quasi [S , E , A ]): Zm [A ] =
163
186
Zm .tailRecM(quasi)(q => (q.index: @ scala.annotation.switch) match {
164
187
case 0 =>
165
188
val a : A = q.value.asInstanceOf [A ]
@@ -168,16 +191,23 @@ package object quasi {
168
191
val sa : S [A ] = q.value.asInstanceOf [S [A ]]
169
192
Zm .map(f(sa))(Right (_))
170
193
case 2 =>
171
- val n : FlatMap [S , Any , A ] = q.value.asInstanceOf [FlatMap [S , Any , A ]]
194
+ val n : FlatMap [S , E , Any , A ] = q.value.asInstanceOf [FlatMap [S , E , Any , A ]]
172
195
Zm .map(this (n.fa))(z => Left (n.f(z)))
173
196
case 3 =>
174
- val n : Ap [S , Any , A ] = q.value.asInstanceOf [Ap [S , Any , A ]]
197
+ val n : Ap [S , E , Any , A ] = q.value.asInstanceOf [Ap [S , E , Any , A ]]
175
198
Zm .map(
176
199
sequential(Za .ap(
177
200
parallel(this (n.ff)))(
178
201
parallel(this (n.fa))))
179
202
)(Right (_))
180
- case _ => scala.Predef .???
203
+ case 4 =>
204
+ val n : Guard [S , E , A ] = q.value.asInstanceOf [Guard [S , E , A ]]
205
+ Zm .map(guard((this (n.fa), n.f.andThen(this (_)))))(Right (_))
206
+ case 5 =>
207
+ val e : E = q.value.asInstanceOf [E ]
208
+ Zm .map(raise(e))(Right (_))
209
+ case _ =>
210
+ sys.error(" unreachable internal state" )
181
211
})
182
212
}
183
213
@@ -197,35 +227,43 @@ package quasi {
197
227
trait MathOp [A ]
198
228
case class ConstInt (value : Int ) extends MathOp [Int ]
199
229
case class Add (x : Int , y : Int ) extends MathOp [Int ]
230
+ case class Div (x : Int , y : Int ) extends MathOp [Int ]
200
231
case class Neg (x : Int ) extends MathOp [Int ]
201
232
202
233
trait Math [F [_]] { underlying =>
203
234
def const (value : Int ): F [Int ]
204
235
def add (x : Int , y : Int ): F [Int ]
236
+ def div (x : Int , y : Int ): F [Int ]
205
237
def neg (x : Int ): F [Int ]
206
238
207
239
final def mapK [G [_]](f : F ~> G ): Math [G ] = new Math [G ] {
208
240
def const (value : Int ): G [Int ] = f(underlying.const(value))
209
241
def add (x : Int , y : Int ): G [Int ] = f(underlying.add(x, y))
242
+ def div (x : Int , y : Int ): G [Int ] = f(underlying.div(x, y))
210
243
def neg (x : Int ): G [Int ] = f(underlying.neg(x))
211
244
}
212
245
}
213
246
214
247
object Math {
215
- def quasi : Math [Quasi [MathOp , ? ]] = new Math [Quasi [MathOp , ? ]] {
216
- def const (value : Int ): Quasi [MathOp , Int ] = Quasi .liftF(ConstInt (value))
217
- def add (x : Int , y : Int ): Quasi [MathOp , Int ] = Quasi .liftF(Add (x, y))
218
- def neg (x : Int ): Quasi [MathOp , Int ] = Quasi .liftF(Neg (x))
248
+ def quasi : Math [Quasi [MathOp , Throwable , ? ]] = new Math [Quasi [MathOp , Throwable , ? ]] {
249
+ def const (value : Int ): Quasi [MathOp , Throwable , Int ] = Quasi .liftF(ConstInt (value))
250
+ def add (x : Int , y : Int ): Quasi [MathOp , Throwable , Int ] = Quasi .liftF(Add (x, y))
251
+ def div (x : Int , y : Int ): Quasi [MathOp , Throwable , Int ] = Quasi .liftF(Div (x, y))
252
+ def neg (x : Int ): Quasi [MathOp , Throwable , Int ] = Quasi .liftF(Neg (x))
219
253
}
220
254
221
- def concur : Math [Concur [MathOp , ? ]] = quasi.mapK[Concur [MathOp , ? ]](Quasi .toConcur)
222
- def subseq : Math [Subseq [MathOp , ? ]] = quasi.mapK[Subseq [MathOp , ? ]](Quasi .toSubseq)
255
+ def concur : Math [Concur [MathOp , Throwable , ? ]] = quasi.mapK[Concur [MathOp , Throwable , ? ]](Quasi .toConcur)
256
+ def subseq : Math [Subseq [MathOp , Throwable , ? ]] = quasi.mapK[Subseq [MathOp , Throwable , ? ]](Quasi .toSubseq)
223
257
}
224
258
225
- val interp : MathOp ~> Id = λ[MathOp ~> Id ] {
226
- case ConstInt (value) => value
227
- case Add (x, y) => x + y
228
- case Neg (x) => - x
259
+ import scala .util .Try
260
+ implicit val parallelTry : Parallel [Try , Try ] = Parallel .identity
261
+
262
+ val interp : MathOp ~> Try = λ[MathOp ~> Try ] {
263
+ case ConstInt (value) => Try (value)
264
+ case Add (x, y) => Try (x + y)
265
+ case Div (x, y) => Try (x / y)
266
+ case Neg (x) => Try (- x)
229
267
}
230
268
231
269
val math = Math .subseq
@@ -244,11 +282,15 @@ package quasi {
244
282
val program2 = for {
245
283
foo <- math.const(0 )
246
284
bar <- List (program0, program1).parSequence
247
- } yield bar.foldLeft(foo)(_ + _)
285
+ } yield bar.foldLeft(foo)(_ / _)
286
+
287
+ val program3 = program2.handleErrorWith(_ => math.const(- 100 ))
248
288
249
- scala.Predef .println(program2)
289
+ scala.Predef .println(" program:" )
290
+ scala.Predef .println(program3)
250
291
251
- val res = Quasi .foldMap(program2.quasi)(interp)
292
+ val res = Quasi .foldMap(program3.quasi)(interp)
293
+ scala.Predef .println(" res:" )
252
294
scala.Predef .println(res)
253
295
254
296
}
0 commit comments