Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+โ†‘Ctrl+โ†“to navigate, Ctrl+๐Ÿ–ฑ๏ธto focus. On Mac, use Cmdinstead of Ctrl.
import Mathlib

/-!
# Monads and randomness
We will first recall the `Option` monad and its properties.

* If `ฮฑ` is a type `Option ฮฑ` is a type.
* Given `a: ฮฑ` we get a term of type `Option ฮฑ` by writing `some a`.
-/

example: Option โ„•
example
:
Option: Type ?u.2 โ†’ Type ?u.2
Option
โ„•: Type
โ„•
:=
pure: {f : Type ?u.5 โ†’ Type ?u.4} โ†’ [self : Pure f] โ†’ {ฮฑ : Type ?u.5} โ†’ ฮฑ โ†’ f ฮฑ
pure
42: ?m.22
42
-- `pure` is terminology from any Monad. /-! * Given `a: Option ฮฑ` and `f : ฮฑ โ†’ ฮฒ` we get a term of type `Option ฮฒ` by writing `a.map f`. * Given `a: Option ฮฑ` and `f: ฮฑ โ†’ Option ฮฒ` we get a term of type `Option ฮฒ` by writing `a.bind f`. For both these it is more pleasant to use the `do` notation. Equivalent to the second is that there is a function `Option Option ฮฑ โ†’ Option ฮฑ` called `join`. -/
Option.join.{u_1} {ฮฑ : Type u_1} (x : Option (Option ฮฑ)) : Option ฮฑ
Option.join: {ฮฑ : Type u_1} โ†’ Option (Option ฮฑ) โ†’ Option ฮฑ
Option.join
Task.spawn.{u} {ฮฑ : Type u} (fn : Unit โ†’ ฮฑ) (prio : Task.Priority := Task.Priority.default) : Task ฮฑ
Task.spawn: {ฮฑ : Type u} โ†’ (Unit โ†’ ฮฑ) โ†’ optParam Task.Priority Task.Priority.default โ†’ Task ฮฑ
Task.spawn
/-! ## IO Monad Roughly wraps with the state of the *real world*. For example, a random number is wrapped in this. -/
IO.rand (lo hi : โ„•) : IO โ„•
IO.rand: โ„• โ†’ โ„• โ†’ IO โ„•
IO.rand
-- IO.rand (lo hi : โ„•) : IO โ„• /-! **Question::** Why not just `โ„•`? * Otherwise we will violate the principle that the value of a function is determined by its arguments. We still do want a natural number. To get this we can `run` the `IO` computation. -/ /-- A random natural number -/ def
rnd: โ„• โ†’ โ„• โ†’ โ„•
rnd
(lo hi :
โ„•: Type
โ„•
) :
โ„•: Type
โ„•
:= ((
IO.rand: โ„• โ†’ โ„• โ†’ IO โ„•
IO.rand
lo hi).
run': {ฮต ฯƒ ฮฑ : Type ?u.136} โ†’ EStateM ฮต ฯƒ ฮฑ โ†’ ฯƒ โ†’ Option ฮฑ
run'
(
(): Unit
()
:
IO.RealWorld: Type
IO.RealWorld
)).
get!: {ฮฑ : Type ?u.149} โ†’ [inst : Inhabited ฮฑ] โ†’ Option ฮฑ โ†’ ฮฑ
get!
/-! This does not lead to a contradiction, though in a way that may be somewhat surprising. -/ /-- A random number between 0 and 100-/ def a :
โ„•: Type
โ„•
:=
rnd: โ„• โ†’ โ„• โ†’ โ„•
rnd
0: ?m.227
0
100: ?m.238
100
/-- A random number between 0 and 100-/ def b :
โ„•: Type
โ„•
:=
rnd: โ„• โ†’ โ„• โ†’ โ„•
rnd
0: ?m.258
0
100: ?m.269
100
/-! We can run these (every run gives a different result). ```lean #eval a -- 23 #eval b -- 96 ``` Interestingly, we can also run the pair of them and get a result on the diagonal. ```lean #eval (a, b) -- (87, 87) ``` -/
40
a -- 23
21
b -- 96
(59, 59)
(a, b) -- (87, 87) /-- A random pair -/ def
rndPair: โ„• โ†’ โ„• โ†’ IO (โ„• ร— โ„•)
rndPair
(lo hi :
โ„•: Type
โ„•
) :
IO: Type โ†’ Type
IO
<|
โ„•: Type
โ„•
ร—
โ„•: Type
โ„•
:= do let
a: ?m.1678
a
โ†
IO.rand: โ„• โ†’ โ„• โ†’ IO โ„•
IO.rand
lo hi let
b: ?m.1700
b
โ†
IO.rand: โ„• โ†’ โ„• โ†’ IO โ„•
IO.rand
lo hi
pure: {f : Type ?u.1703 โ†’ Type ?u.1702} โ†’ [self : Pure f] โ†’ {ฮฑ : Type ?u.1703} โ†’ ฮฑ โ†’ f ฮฑ
pure
(
a: ?m.1678
a
,
b: ?m.1700
b
)
(86, 1)
rndPair: โ„• โ†’ โ„• โ†’ IO (โ„• ร— โ„•)
rndPair
0: ?m.1984
0
100: ?m.1995
100
-- (47, 30) /-! ```lean #eval a -- 23 #eval b -- 96 #eval (a, b) -- (87, 87) ``` -/
IO.RealWorld : Type
IO.RealWorld: Type
IO.RealWorld
Unit : Type
Unit: Type
Unit
example: a = b
example
: a = b :=

Goals accomplished! ๐Ÿ™

a = b

Goals accomplished! ๐Ÿ™
-- #reduce a -- times out -- example : a = 23 := by rfl -- fails
Option.orElse.{u_1} {ฮฑ : Type u_1} (aโœ : Option ฮฑ) (aโœยน : Unit โ†’ Option ฮฑ) : Option ฮฑ
Option.orElse: {ฮฑ : Type u_1} โ†’ Option ฮฑ โ†’ (Unit โ†’ Option ฮฑ) โ†’ Option ฮฑ
Option.orElse
some 3
(
some: {ฮฑ : Type ?u.2540} โ†’ ฮฑ โ†’ Option ฮฑ
some
3: ?m.2543
3
).
orElse: {ฮฑ : Type ?u.2551} โ†’ Option ฮฑ โ†’ (Unit โ†’ Option ฮฑ) โ†’ Option ฮฑ
orElse
(fun
_: ?m.2558
_
โ†ฆ
some: {ฮฑ : Type ?u.2560} โ†’ ฮฑ โ†’ Option ฮฑ
some
4: ?m.2565
4
) -- some 3
some 4
(
none: {ฮฑ : Type ?u.3138} โ†’ Option ฮฑ
none
).
orElse: {ฮฑ : Type ?u.3140} โ†’ Option ฮฑ โ†’ (Unit โ†’ Option ฮฑ) โ†’ Option ฮฑ
orElse
(fun
_: ?m.3147
_
โ†ฆ
some: {ฮฑ : Type ?u.3149} โ†’ ฮฑ โ†’ Option ฮฑ
some
4: ?m.3154
4
) -- some 4