After this commit, we have to use an explicit `discard` in code such as ``` def g (x : Nat) : IO Nat := ... def f (x : Nat) : IO Unit := do discard <| g x -- type error without the `discard` IO.println x ``` Motivation: prevent users from making mistakes such as ``` def f (xs : Array Nat) : IO Unit := do xs.set! 0 1 IO.println xs ``` when they meant to write ``` def f (xs : Array Nat) : IO Unit := do let xs := xs.set! 0 1 IO.println xs ```
36 lines
922 B
Text
36 lines
922 B
Text
#lang lean4
|
||
#eval id (α := IO _) do
|
||
let t1 ← IO.asTask $ Nat.forM 10 fun _ => IO.println "hi";
|
||
let t2 ← IO.asTask $ Nat.forM 10 fun _ => IO.println "ho";
|
||
IO.ofExcept t1.get
|
||
|
||
#eval id (α := IO _) do
|
||
let t1 ← IO.mapTask IO.println (Task.spawn fun _ => "ha");
|
||
pure ()
|
||
|
||
#eval id (α := IO _) do
|
||
let t1 ← IO.bindTask (Task.spawn fun _ => "hu") fun s =>
|
||
IO.asTask (IO.println s);
|
||
pure ()
|
||
|
||
#eval id (α := IO _) do
|
||
let t1 ← IO.asTask do {
|
||
let c ← IO.checkCanceled;
|
||
IO.println (if c then "canceled!" else "done!")
|
||
};
|
||
pure ()
|
||
|
||
#eval id (α := IO _) do
|
||
let t1 ← IO.asTask do {
|
||
let c ← IO.checkCanceled;
|
||
IO.println (if c then "canceled! 2" else "done! 2")
|
||
};
|
||
IO.cancel t1;
|
||
discard $ IO.wait t1;
|
||
pure ()
|
||
|
||
#eval IO.waitAny [
|
||
Task.spawn fun _ => dbgSleep 2 fun _ => "A",
|
||
Task.spawn fun _ => dbgSleep 3 fun _ => "B",
|
||
Task.spawn fun _ => dbgSleep 1 fun _ => "C"
|
||
]
|