-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscheduling.effekt
73 lines (64 loc) · 2.13 KB
/
scheduling.effekt
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
module reactive/interleave
import immutable/option
import reactive/types
import reactive/effects
def interleave[T1, T2, R]{ task1: => T1 / Scheduling } {task2: => T2 / Scheduling } {loop: {() => Option[T1]}{() => Option[T2]} => R }: R = region this {
var p1: => Option[T1] at {this, task1} in this = fun(){None()}
var p2: => Option[T2] at {this, task2} in this = fun(){None()}
p1 = fun(){
try {
val t = Some(task1())
p1 = fun(){t}
t
} with Scheduling {
def tick() = {p1 = fun(){ resume(()) }; None()}
}
}
p2 = fun(){
try {
val t = Some(task2())
p2 = fun(){t}
t
} with Scheduling {
def tick() = {p2 = fun(){ resume(()) }; None()}
}
}
loop{() => p1()}{() => p2()}
}
def bothAreDone[T1, T2] {task1: => T1 / Scheduling} {task2: => T2 / Scheduling}: Tuple2[T1, T2] / Scheduling = {
def loop{p1: => Option[T1]}{p2: => Option[T2]}: Tuple2[T1, T2] = {
(p1(), p2()) match {
case (Some(t1), Some(t2)) => do tick(); Tuple2(t1, t2)
case (_,_) => do tick(); loop{p1}{p2}
}
}
interleave{task1}{task2}{loop}
}
def oneIsDone[T1, T2]{ task1: => T1 / Scheduling } {task2: => T2 / Scheduling }: Either[T1, T2] / Scheduling = {
def loop{p1: => Option[T1]} {p2: => Option[T2]}: Either[T1, T2] = {
p1() match {
case Some(t1) => do tick(); Left(t1)
case None() => p2() match {
case Some(t2) => do tick(); Right(t2)
case None() => do tick(); loop{p1}{p2}
}
}
}
interleave{task1}{task2}{loop}
}
def forever[T] { task: => T / Scheduling }: Nothing / Scheduling = try {
task()
forever { task }
} with Scheduling {
def tick() = { do tick(); resume(())}
}
def run[T]{task: => T / { Scheduling, Exception[ReactiveError] }}: Unit = {
try{
task()
println("") // Needed bug report.
} with Scheduling {
def tick() = resume(())
} with Exception[ReactiveError] {
def raise[ReactiveError](e, msg) = println(msg)
}
}