1
+ module search
2
+
3
+ import stream
4
+
5
+
6
+ effect fork(): Bool
7
+ effect fail(): Nothing
8
+
9
+ def select[A] { stream: () => Unit / emit[A] }: A / {fork, fail} = {
10
+ def body(): A / emit[A] = {
11
+ stream()
12
+ do fail()
13
+ }
14
+ try {
15
+ body()
16
+ } with emit[A] { value =>
17
+ if (do fork()) {
18
+ return value
19
+ } else {
20
+ resume(())
21
+ }
22
+ }
23
+ }
24
+
25
+ def results[R] { query: () => R / {fork, fail} }: Unit / emit[R] =
26
+ try {
27
+ do emit(query())
28
+ } with fork { () =>
29
+ resume(true)
30
+ resume(false)
31
+ } with fail { () =>
32
+ ()
33
+ }
34
+
35
+ def choose[A](items: List[A]): A / {fork, fail} =
36
+ select { items.each }
37
+
38
+ def choice[A] { action1: () => A } { action2: () => A }: A / fork =
39
+ if (do fork()) { action1() } else { action2() }
40
+
41
+ def where(condition: Bool): Unit / fail =
42
+ if (condition) { () } else { do fail() }
43
+
44
+
45
+ type Key = String
46
+ type Option = String
47
+
48
+ type Menu = List[(Key, List[Option])]
49
+ type Meal = List[(Key, Option)]
50
+
51
+ def allMeals(menu: Menu): Meal / {fork, fail} =
52
+ menu.map { case (category, options) => (category, options.choose) }
53
+
54
+ def main() = {
55
+ val menu = [
56
+ ("Protein", ["Chicken", "Beef", "Tofu"]),
57
+ ("Carbs", ["Rice", "Pasta", "French Fries"]),
58
+ ("Veggie", ["Bell Pepper", "Brocolli"])
59
+ ]
60
+ for[Meal] { results { allMeals(menu) } } { meal =>
61
+ meal.foreach { case (key, option) => println(key ++ "," ++ option ++ " ") }
62
+ println("")
63
+ }
64
+ }
0 commit comments