Skip to content
This repository was archived by the owner on Jan 5, 2025. It is now read-only.

Commit 82d4c52

Browse files
committed
演習問題を解いた
1 parent 858802c commit 82d4c52

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/- Check the monad contract for `State σ` and `Except ε`. -/
2+
set_option autoImplicit false
3+
4+
section Textbook
5+
6+
variable {α : Type} {σ : Type}
7+
8+
def State (σ : Type) (α : Type) : Type :=
9+
σ → (σ × α)
10+
11+
def ok (x : α) : State σ α :=
12+
fun s => (s, x)
13+
14+
instance : Monad (State σ) where
15+
pure x := fun s => (s, x)
16+
bind first next :=
17+
fun s =>
18+
let (s', x) := first s
19+
next x s'
20+
21+
end Textbook
22+
23+
section
24+
variable (σ : Type)
25+
26+
instance : LawfulMonad (State σ) where
27+
map_const := by intros; rfl
28+
id_map := by intros; rfl
29+
seqLeft_eq := by intros; rfl
30+
seqRight_eq := by intros; rfl
31+
pure_seq := by intros; rfl
32+
bind_pure_comp := by intros; rfl
33+
bind_assoc := by intros; rfl
34+
bind_map := by intros; rfl
35+
pure_bind := by intros; rfl
36+
37+
-- 既に標準ライブラリに存在する
38+
#synth Monad (Except σ)
39+
40+
instance : LawfulMonad (Except σ) where
41+
map_const := by intros; rfl
42+
id_map := by
43+
intro α x
44+
cases x <;> rfl
45+
seqLeft_eq := by
46+
intro α β x y
47+
cases x <;> rfl
48+
seqRight_eq := by
49+
intro α β x y
50+
cases x <;> cases y
51+
all_goals rfl
52+
pure_seq := by intros; rfl
53+
bind_pure_comp := by intros; rfl
54+
bind_assoc := by
55+
intro α β γ x f g
56+
cases x <;> rfl
57+
bind_map := by intros; rfl
58+
pure_bind := by intros; rfl
59+
end
60+
/- Adapt the reader monad example so that it can also indicate failure when the custom operator is not defined, rather than just returning zero. In other words, given these definitions:
61+
62+
`def ReaderOption (ρ : Type) (α : Type) : Type := ρ → Option α
63+
64+
def ReaderExcept (ε : Type) (ρ : Type) (α : Type) : Type := ρ → Except ε α`
65+
66+
do the following:
67+
68+
1. Write suitable `pure` and `bind` functions
69+
2. Check that these functions satisfy the `Monad` contract
70+
3. Write `Monad` instances for `ReaderOption` and `ReaderExcept`
71+
4. Define suitable `applyPrim` operators and test them with `evaluateM` on some example expressions
72+
-/
73+
section
74+
75+
def ReaderOption (ρ : Type) (α : Type) : Type := ρ → Option α
76+
77+
def ReaderExcept (ε : Type) (ρ : Type) (α : Type) : Type := ρ → Except ε α
78+
79+
variable {ρ : Type} {ε : Type}
80+
81+
instance : Monad (ReaderOption ρ) where
82+
pure x := fun _ => some x
83+
bind first next :=
84+
fun r =>
85+
match first r with
86+
| none => none
87+
| some x => next x r
88+
89+
instance : Monad (ReaderExcept ε ρ) where
90+
pure x := fun _ => Except.ok x
91+
bind first next :=
92+
fun r =>
93+
match first r with
94+
| Except.error e => Except.error e
95+
| Except.ok x => next x r
96+
97+
instance : LawfulMonad (ReaderOption ρ) where
98+
map_const := by intros; rfl
99+
id_map := by
100+
intro α f
101+
funext r
102+
dsimp [Functor.map]
103+
cases f r <;> rfl
104+
seqLeft_eq := by
105+
intro α β x y
106+
funext r
107+
dsimp [Functor.map, SeqLeft.seqLeft, Seq.seq]
108+
cases x r <;> try simp
109+
seqRight_eq := by
110+
intro α β x y
111+
funext r
112+
dsimp [Functor.map, SeqRight.seqRight, Seq.seq]
113+
cases x r <;> try simp
114+
cases y r <;> rfl
115+
pure_seq := by intros; rfl
116+
bind_pure_comp := by intros; rfl
117+
bind_assoc := by
118+
intro α β γ x f g
119+
funext r
120+
dsimp [Bind.bind]
121+
cases x r <;> rfl
122+
bind_map := by intros; rfl
123+
pure_bind := by intros; rfl
124+
125+
instance : LawfulMonad (ReaderExcept ε ρ) where
126+
map_const := by intros; rfl
127+
id_map := by
128+
intro α f
129+
funext r
130+
dsimp [Functor.map]
131+
cases f r <;> rfl
132+
seqLeft_eq := by
133+
intro α β x y
134+
funext r
135+
dsimp [Functor.map, SeqLeft.seqLeft, Seq.seq]
136+
cases x r <;> try simp
137+
seqRight_eq := by
138+
intro α β x y
139+
funext r
140+
dsimp [Functor.map, SeqRight.seqRight, Seq.seq]
141+
cases x r <;> try simp
142+
cases y r <;> rfl
143+
pure_seq := by intros; rfl
144+
bind_pure_comp := by intros; rfl
145+
bind_assoc := by
146+
intro α β γ x f g
147+
funext r
148+
dsimp [Bind.bind]
149+
cases x r <;> rfl
150+
bind_map := by intros; rfl
151+
pure_bind := by intros; rfl
152+
153+
inductive Expr (op : Type) where
154+
| const : Int → Expr op
155+
| prim : op → Expr op → Expr op → Expr op
156+
157+
inductive Arith where
158+
| plus
159+
| minus
160+
| times
161+
| div
162+
163+
inductive Prim (special : Type) where
164+
| plus
165+
| minus
166+
| times
167+
| other : special → Prim special
168+
169+
def «3×2» : Expr (Prim String) := Expr.prim .times (.const 3) (.const 2)
170+
171+
def «5+4» : Expr (Prim String) := Expr.prim .plus (.const 5) (.const 4)
172+
173+
def «0» : Expr (Prim String) := Expr.const 0
174+
175+
variable {m : TypeType}
176+
177+
def applyPrim [Monad m] {special : Type} (applySpecial : special → Int → Int → m Int) : Prim special → Int → Int → m Int
178+
| Prim.plus, x, y => pure (x + y)
179+
| Prim.minus, x, y => pure (x - y)
180+
| Prim.times, x, y => pure (x * y)
181+
| Prim.other op, x, y => applySpecial op x y
182+
183+
def evaluateM [Monad m] {special : Type} (applySpecial : special → Int → Int → m Int): Expr (Prim special) → m Int
184+
| Expr.const i => pure i
185+
| Expr.prim p e1 e2 =>
186+
evaluateM applySpecial e1 >>= fun v1 =>
187+
evaluateM applySpecial e2 >>= fun v2 =>
188+
applyPrim applySpecial p v1 v2
189+
190+
abbrev Env : Type := List (String × (Int → Int → Option Int))
191+
192+
def div (x y : Int) : Option Int := if y = 0 then none else some (x / y)
193+
194+
def exampleEnv : Env := [("div", div)]
195+
196+
def applyPrimReader (op : String) (x : Int) (y : Int) : ReaderOption Env Int := do
197+
let env ← pure
198+
match env.lookup op with
199+
| none => pure 0
200+
| some f =>
201+
match f x y with
202+
| none => fun _ => none
203+
| some z => pure z
204+
205+
#eval evaluateM applyPrimReader (Expr.prim (Prim.other "div") «5+4» «0») exampleEnv
206+
207+
end

0 commit comments

Comments
 (0)