1+ case class Test1 (); case class Test2 (); case class Test3 ();
2+ case class Test4 (); case class Test5 (); case class Test6 ();
3+
4+ sealed abstract class DSL {
5+ def cont [P1 >: this .type <: DSL , P2 <: DSL ](continuation : => P2 ) =
6+ Continue [P1 , P2 ](() => this , () => continuation)
7+ }
8+ case class Continue [P1 <: DSL , P2 <: DSL ](p1 : () => P1 , p2 : () => P2 ) extends DSL
9+
10+ trait More [- A ] {}
11+ case class Out [C <: More [A ], A ](c : C , v : A ) extends DSL
12+ case class Nop () extends DSL
13+
14+ val decision1 : Boolean = true ;
15+ val decision2 : Boolean = false ;
16+
17+ type P [
18+ ChanA <: More [Test1 | Test2 ],
19+ ChanB <: More [Test3 | Test4 ],
20+ ChanC <: More [Test5 | Test6 ]] =
21+ ((Out [ChanA ,Test1 ] Continue ((Out [ChanB ,Test3 ] Continue Nop )| (Out [ChanB ,Test4 ] Continue Nop ))) // works if remove first 'Continue Nop'
22+ | (Out [ChanA ,Test2 ] Continue ((Out [ChanC ,Test5 ] Continue Nop )| (Out [ChanC ,Test6 ] Continue Nop ))))
23+
24+
25+ def p ( chanA : More [Test1 | Test2 ], chanB : More [Test3 | Test4 ], chanC : More [Test5 | Test6 ])
26+ : P [chanA.type ,chanB.type ,chanC.type ] = {
27+ if (decision1){
28+ Out (chanA,Test1 ()) cont {
29+ if (decision2){
30+ Out (chanB,Test3 ()) cont Nop () // works if replace with 'Out(chanB,Test3())'
31+ }
32+ else {
33+ Out (chanB,Test4 ()) cont Nop ()
34+ }
35+ }
36+ }
37+ else {
38+ Out (chanA,Test2 ()) cont {
39+ if (decision2){
40+ Out (chanC,Test5 ()) cont Nop ()
41+ }
42+ else {
43+ Out (chanC,Test6 ()) cont Nop ()
44+ }
45+ }
46+ }
47+ }
0 commit comments