@@ -14,55 +14,57 @@ end boundary
1414
1515import boundary .{Label , break }
1616
17- class Async
17+ @ capability trait Async
18+ object Async :
19+ def blocking [T ](body : Async ?=> T ): T = ???
20+
1821class Future [+ T ]:
1922 this : Future [T ]^ =>
20- def await (using Async ^ ): T = ???
23+ def await (using Async ): T = ???
2124object Future :
22- def apply [T ](op : Async ^ ?=> T )(using Async ): Future [T ]^ {op} = ???
25+ def apply [T ](op : Async ?=> T )(using Async ): Future [T ]^ {op} = ???
26+
27+ enum Result [+ T , + E ]:
28+ case Ok [+ T ](value : T ) extends Result [T , Nothing ]
29+ case Err [+ E ](error : E ) extends Result [Nothing , E ]
2330
24- abstract class Result [+ T , + E ]
25- case class Ok [+ T ](value : T ) extends Result [T , Nothing ]
26- case class Err [+ E ](value : E ) extends Result [Nothing , E ]
2731
2832object Result :
29- extension [T , E ](r : Result [T , E ])
33+ extension [T , E ](r : Result [T , E ]^ )( using Label [ Err [ E ]] )
3034
3135 /** `_.ok` propagates Err to current Label */
32- inline def ok ( using Label [ Result [ Nothing , E ]]) : T = r match
33- case r : Ok [_] => r. value
34- case err => break(err. asInstanceOf [Err [E ]])
36+ def ok : T = r match
37+ case Ok (value) => value
38+ case Err (value) => break[Err [E ]]( Err (value) )
3539
3640 transparent inline def apply [T , E ](inline body : Label [Result [T , E ]] ?=> T ): Result [T , E ] =
37- boundary :
38- val result = body
39- Ok (result)
41+ boundary(Ok (body))
4042
4143 // same as apply, but not an inline method
4244 def make [T , E ](body : Label [Result [T , E ]] ?=> T ): Result [T , E ] =
43- boundary :
44- val result = body
45- Ok (result)
45+ boundary(Ok (body))
4646
4747end Result
4848
4949def test [T , E ](using Async ) =
50- val good1 : List [Future [Result [T , E ]]] => Future [Result [List [T ], E ]] = frs =>
51- Future :
52- Result :
53- frs.map(_.await.ok) // OK
50+ import Result .*
51+ Async .blocking: async ?=>
52+ val good1 : List [Future [Result [T , E ]]] => Future [Result [List [T ], E ]] = frs =>
53+ Future :
54+ Result :
55+ frs.map(_.await.ok) // OK
5456
55- val good2 : Result [Future [T ], E ] => Future [Result [T , E ]] = rf =>
56- Future :
57- Result :
58- rf.ok.await // OK, Future argument has type Result[T]
57+ val good2 : Result [Future [T ], E ] => Future [Result [T , E ]] = rf =>
58+ Future :
59+ Result :
60+ rf.ok.await // OK, Future argument has type Result[T]
5961
60- def fail3 (fr : Future [Result [T , E ]]^ ) =
61- Result :
62- Future : // error, escaping label from Result
63- fr.await.ok
62+ def fail3 (fr : Future [Result [T , E ]]^ ) =
63+ Result :
64+ Future : // error, escaping label from Result
65+ fr.await.ok
6466
65- def fail4 (fr : Future [Result [T , E ]]^ ) =
66- Result .make: // error, escaping label from Result
67- Future :
68- fr.await.ok
67+ def fail4 [ T , E ] (fr : Future [Result [T , E ]]^ ) =
68+ Result .make: // lbl ?=> // error, escaping label from Result
69+ Future : fut ?=>
70+ fr.await.ok
0 commit comments