@@ -9,6 +9,7 @@ http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Cont.html
9
9
-/
10
10
11
11
import tactic.ext
12
+ import category.monad.basic category.monad.writer
12
13
13
14
universes u v w
14
15
@@ -17,13 +18,12 @@ structure monad_cont.label (α : Type w) (m : Type u → Type v) (β : Type u) :
17
18
18
19
def monad_cont.goto {α β} {m : Type u → Type v} (f : monad_cont.label α m β) (x : α) := f.apply x
19
20
20
- class monad_cont (m : Type u → Type v)
21
- extends monad m :=
21
+ class monad_cont (m : Type u → Type v) :=
22
22
(call_cc : Π {α β}, ((monad_cont.label α m β) → m α) → m α)
23
23
24
24
open monad_cont
25
25
26
- class is_lawful_monad_cont (m : Type u → Type v) [monad_cont m]
26
+ class is_lawful_monad_cont (m : Type u → Type v) [monad m] [ monad_cont m]
27
27
extends is_lawful_monad m :=
28
28
(call_cc_bind_right {α ω γ} (cmd : m α) (next : (label ω m γ) → α → m ω) :
29
29
call_cc (λ f, cmd >>= next f) = cmd >>= λ x, call_cc (λ f, next f x))
@@ -36,6 +36,8 @@ export is_lawful_monad_cont
36
36
37
37
def cont_t (r : Type u) (m : Type u → Type v) (α : Type w) := (α → m r) → m r
38
38
39
+ @[reducible] def cont (r : Type u) (α : Type w) := cont_t r id α
40
+
39
41
namespace cont_t
40
42
41
43
export monad_cont (label goto)
@@ -55,6 +57,11 @@ def with_cont_t (f : (β → m r) → α → m r) (x : cont_t r m α) : cont_t r
55
57
lemma run_with_cont_t (f : (β → m r) → α → m r) (x : cont_t r m α) :
56
58
run (with_cont_t f x) = run x ∘ f := rfl
57
59
60
+ @[extensionality]
61
+ protected lemma ext {x y : cont_t r m α}
62
+ (h : ∀ f, x.run f = y.run f) :
63
+ x = y := by { ext; apply h }
64
+
58
65
instance : monad (cont_t r m) :=
59
66
{ pure := λ α x f, f x,
60
67
bind := λ α β x f g, x $ λ i, f i g }
@@ -64,12 +71,15 @@ instance : is_lawful_monad (cont_t r m) :=
64
71
pure_bind := by { intros, ext, refl },
65
72
bind_assoc := by { intros, ext, refl } }
66
73
74
+ def cont_t.monad_lift [monad m] {α} : m α → cont_t r m α :=
75
+ λ x f, x >>= f
76
+
67
77
instance [monad m] : has_monad_lift m (cont_t r m) :=
68
- { monad_lift := λ a x f, x >>= f }
78
+ { monad_lift := λ α, cont_t.monad_lift }
69
79
70
80
lemma monad_lift_bind [monad m] [is_lawful_monad m] {α β} (x : m α) (f : α → m β) :
71
81
(monad_lift (x >>= f) : cont_t r m β) = monad_lift x >>= monad_lift ∘ f :=
72
- by { ext, simp only [monad_lift,has_monad_lift.monad_lift,(∘),(>>=),bind_assoc,id.def] }
82
+ by { ext, simp only [monad_lift,has_monad_lift.monad_lift,(∘),(>>=),bind_assoc,id.def,run,cont_t.monad_lift ] }
73
83
74
84
instance : monad_cont (cont_t r m) :=
75
85
{ call_cc := λ α β f g, f ⟨λ x h, g x⟩ g }
@@ -79,4 +89,93 @@ instance : is_lawful_monad_cont (cont_t r m) :=
79
89
call_cc_bind_left := by intros; ext; refl,
80
90
call_cc_dummy := by intros; ext; refl }
81
91
92
+ instance (ε) [monad_except ε m] : monad_except ε (cont_t r m) :=
93
+ { throw := λ x e f, throw e,
94
+ catch := λ α act h f, catch (act f) (λ e, h e f) }
95
+
96
+ instance : monad_run (λ α, (α → m r) → ulift.{u v} (m r)) (cont_t.{u v u} r m) :=
97
+ { run := λ α f x, ⟨ f x ⟩ }
98
+
82
99
end cont_t
100
+
101
+ variables {m : Type u → Type v} [monad m]
102
+
103
+ def except_t.mk_label {α β ε} : label (except.{u u} ε α) m β → label α (except_t ε m) β
104
+ | ⟨ f ⟩ := ⟨ λ a, monad_lift $ f (except.ok a) ⟩
105
+
106
+ lemma except_t.goto_mk_label {α β ε : Type *} (x : label (except.{u u} ε α) m β) (i : α) :
107
+ goto (except_t.mk_label x) i = ⟨ except.ok <$> goto x (except.ok i) ⟩ := by cases x; refl
108
+
109
+ def except_t.call_cc {ε} [monad_cont m] {α β : Type *} (f : label α (except_t ε m) β → except_t ε m α) : except_t ε m α :=
110
+ except_t.mk (call_cc $ λ x : label _ m β, except_t.run $ f (except_t.mk_label x) : m (except ε α))
111
+
112
+ instance {ε} [monad_cont m] : monad_cont (except_t ε m) :=
113
+ { call_cc := λ α β, except_t.call_cc }
114
+
115
+ instance {ε} [monad_cont m] [is_lawful_monad_cont m] : is_lawful_monad_cont (except_t ε m) :=
116
+ { call_cc_bind_right := by { intros, simp [call_cc,except_t.call_cc,call_cc_bind_right], ext, dsimp, congr, ext ⟨ ⟩; simp [except_t.bind_cont,@call_cc_dummy m _], },
117
+ call_cc_bind_left := by { intros, simp [call_cc,except_t.call_cc,call_cc_bind_right,except_t.goto_mk_label,map_eq_bind_pure_comp,bind_assoc,@call_cc_bind_left m _], ext, refl },
118
+ call_cc_dummy := by { intros, simp [call_cc,except_t.call_cc,@call_cc_dummy m _], ext, refl }, }
119
+
120
+ def option_t.mk_label {α β} : label (option.{u} α) m β → label α (option_t m) β
121
+ | ⟨ f ⟩ := ⟨ λ a, monad_lift $ f (some a) ⟩
122
+
123
+ lemma option_t.goto_mk_label {α β : Type *} (x : label (option.{u} α) m β) (i : α) :
124
+ goto (option_t.mk_label x) i = ⟨ some <$> goto x (some i) ⟩ := by cases x; refl
125
+
126
+ def option_t.call_cc [monad_cont m] {α β : Type *} (f : label α (option_t m) β → option_t m α) : option_t m α :=
127
+ option_t.mk (call_cc $ λ x : label _ m β, option_t.run $ f (option_t.mk_label x) : m (option α))
128
+
129
+ instance [monad_cont m] : monad_cont (option_t m) :=
130
+ { call_cc := λ α β, option_t.call_cc }
131
+
132
+ instance [monad_cont m] [is_lawful_monad_cont m] : is_lawful_monad_cont (option_t m) :=
133
+ { call_cc_bind_right := by { intros, simp [call_cc,option_t.call_cc,call_cc_bind_right], ext, dsimp, congr, ext ⟨ ⟩; simp [option_t.bind_cont,@call_cc_dummy m _], },
134
+ call_cc_bind_left := by { intros, simp [call_cc,option_t.call_cc,call_cc_bind_right,option_t.goto_mk_label,map_eq_bind_pure_comp,bind_assoc,@call_cc_bind_left m _], ext, refl },
135
+ call_cc_dummy := by { intros, simp [call_cc,option_t.call_cc,@call_cc_dummy m _], ext, refl }, }
136
+
137
+ def writer_t.mk_label {α β ω} [has_one ω] : label (α × ω) m β → label α (writer_t ω m) β
138
+ | ⟨ f ⟩ := ⟨ λ a, monad_lift $ f (a,1 ) ⟩
139
+
140
+ lemma writer_t.goto_mk_label {α β ω : Type *} [has_one ω] (x : label (α × ω) m β) (i : α) :
141
+ goto (writer_t.mk_label x) i = monad_lift (goto x (i,1 )) := by cases x; refl
142
+
143
+ def writer_t.call_cc [monad_cont m] {α β ω : Type *} [has_one ω] (f : label α (writer_t ω m) β → writer_t ω m α) : writer_t ω m α :=
144
+ ⟨ call_cc (writer_t.run ∘ f ∘ writer_t.mk_label : label (α × ω) m β → m (α × ω)) ⟩
145
+
146
+ instance (ω) [monad m] [has_one ω] [monad_cont m] : monad_cont (writer_t ω m) :=
147
+ { call_cc := λ α β, writer_t.call_cc }
148
+
149
+ def state_t.mk_label {α β σ : Type u} : label (α × σ) m (β × σ) → label α (state_t σ m) β
150
+ | ⟨ f ⟩ := ⟨ λ a, ⟨ λ s, f (a,s) ⟩ ⟩
151
+
152
+ lemma state_t.goto_mk_label {α β σ : Type u} (x : label (α × σ) m (β × σ)) (i : α) :
153
+ goto (state_t.mk_label x) i = ⟨ λ s, (goto x (i,s)) ⟩ := by cases x; refl
154
+
155
+ def state_t.call_cc {σ} [monad_cont m] {α β : Type *} (f : label α (state_t σ m) β → state_t σ m α) : state_t σ m α :=
156
+ ⟨ λ r, call_cc (λ f', (f $ state_t.mk_label f').run r) ⟩
157
+
158
+ instance {σ} [monad_cont m] : monad_cont (state_t σ m) :=
159
+ { call_cc := λ α β, state_t.call_cc }
160
+
161
+ instance {σ} [monad_cont m] [is_lawful_monad_cont m] : is_lawful_monad_cont (state_t σ m) :=
162
+ { call_cc_bind_right := by { intros, simp [call_cc,state_t.call_cc,call_cc_bind_right,(>>=),state_t.bind], ext, dsimp, congr, ext ⟨x₀,x₁⟩, refl },
163
+ call_cc_bind_left := by { intros, simp [call_cc,state_t.call_cc,call_cc_bind_left,(>>=),state_t.bind,state_t.goto_mk_label], ext, refl },
164
+ call_cc_dummy := by { intros, simp [call_cc,state_t.call_cc,call_cc_bind_right,(>>=),state_t.bind,@call_cc_dummy m _], ext, refl }, }
165
+
166
+ def reader_t.mk_label {α β} (ρ) : label α m β → label α (reader_t ρ m) β
167
+ | ⟨ f ⟩ := ⟨ monad_lift ∘ f ⟩
168
+
169
+ lemma reader_t.goto_mk_label {α ρ β} (x : label α m β) (i : α) :
170
+ goto (reader_t.mk_label ρ x) i = monad_lift (goto x i) := by cases x; refl
171
+
172
+ def reader_t.call_cc {ε} [monad_cont m] {α β : Type *} (f : label α (reader_t ε m) β → reader_t ε m α) : reader_t ε m α :=
173
+ ⟨ λ r, call_cc (λ f', (f $ reader_t.mk_label _ f').run r) ⟩
174
+
175
+ instance {ρ} [monad_cont m] : monad_cont (reader_t ρ m) :=
176
+ { call_cc := λ α β, reader_t.call_cc }
177
+
178
+ instance {ρ} [monad_cont m] [is_lawful_monad_cont m] : is_lawful_monad_cont (reader_t ρ m) :=
179
+ { call_cc_bind_right := by { intros, simp [call_cc,reader_t.call_cc,call_cc_bind_right], ext, refl },
180
+ call_cc_bind_left := by { intros, simp [call_cc,reader_t.call_cc,call_cc_bind_left,reader_t.goto_mk_label], ext, refl },
181
+ call_cc_dummy := by { intros, simp [call_cc,reader_t.call_cc,@call_cc_dummy m _], ext, refl } }
0 commit comments