85 lines
2 KiB
Text
85 lines
2 KiB
Text
import init.control.coroutine
|
||
|
||
universes u v
|
||
open coroutine
|
||
|
||
namespace ex1
|
||
|
||
inductive tree (α : Type u)
|
||
| leaf {} : tree
|
||
| node : tree → α → tree → tree
|
||
|
||
/-- Coroutine as generators/iterators -/
|
||
def visit {α : Type v} : tree α → coroutine unit α unit
|
||
| tree.leaf := pure ()
|
||
| (tree.node l a r) := do
|
||
visit l,
|
||
yield a,
|
||
visit r
|
||
|
||
def tst {α : Type} [has_to_string α] (t : tree α) : except_t string io unit :=
|
||
do c ← pure $ visit t,
|
||
(yielded v₁ c) ← pure $ resume c (),
|
||
(yielded v₂ c) ← pure $ resume c (),
|
||
io.println $ to_string v₁,
|
||
io.println $ to_string v₂,
|
||
pure ()
|
||
|
||
#eval tst (tree.node (tree.node (tree.node tree.leaf 5 tree.leaf) 10 (tree.node tree.leaf 20 tree.leaf)) 30 tree.leaf)
|
||
|
||
end ex1
|
||
|
||
namespace ex2
|
||
|
||
def ex : state_t nat (coroutine nat string) unit :=
|
||
do
|
||
x ← read,
|
||
y ← get,
|
||
put (y+5),
|
||
yield ("1) val: " ++ to_string (x+y)),
|
||
x ← read,
|
||
y ← get,
|
||
yield ("2) val: " ++ to_string (x+y)),
|
||
pure ()
|
||
|
||
def tst2 : except_t string io unit :=
|
||
do let c := state_t.run ex 5,
|
||
(yielded r c₁) ← pure $ resume c 10,
|
||
io.println r,
|
||
(yielded r c₂) ← pure $ resume c₁ 20,
|
||
io.println r,
|
||
(done _) ← pure $ resume c₂ 30,
|
||
(yielded r c₃) ← pure $ resume c₁ 100,
|
||
io.println r,
|
||
io.println "done",
|
||
pure ()
|
||
|
||
#eval tst2
|
||
|
||
def ex3 : except_t string (coroutine_io nat string) unit :=
|
||
do
|
||
x ← read,
|
||
io.println $ "got " ++ to_string x,
|
||
yield ("1) val: " ++ to_string x),
|
||
x ← read,
|
||
io.println $ "got " ++ to_string x,
|
||
yield ("2) val: " ++ to_string x),
|
||
throw "my_error"
|
||
|
||
open coroutine_io
|
||
def tst3 : except_t string io unit :=
|
||
do let c := ex3.run,
|
||
(yielded r c₁) ← monad_lift $ c.resume 10,
|
||
io.println r,
|
||
(yielded r c₂) ← monad_lift $ c₁.resume 20,
|
||
io.println r,
|
||
(done (except.error e)) ← monad_lift $ c₂.resume 30,
|
||
io.println $ "error: " ++ e,
|
||
(yielded r c₃) ← monad_lift $ c₁.resume 100,
|
||
io.println r,
|
||
io.println "done",
|
||
pure ()
|
||
|
||
#eval tst3
|
||
|
||
end ex2
|