1 | include "basics/types.ma". |
---|
2 | include "basics/relations.ma". |
---|
3 | include "utilities/setoids.ma". |
---|
4 | include "utilities/proper.ma". |
---|
5 | |
---|
6 | record MonadDefinition : Type[1] ≝ { |
---|
7 | monad : Type[0] → Type[0] ; |
---|
8 | m_return : ∀X. X → monad X ; |
---|
9 | m_bind : ∀X,Y. monad X → (X → monad Y) → monad Y |
---|
10 | }. |
---|
11 | |
---|
12 | notation "m »= f" with precedence 49 |
---|
13 | for @{'m_bind $m $f) }. |
---|
14 | |
---|
15 | notation > "!_ e; e'" |
---|
16 | with precedence 48 for @{'m_bind ${e} (λ_. ${e'})}. |
---|
17 | notation > "! ident v ← e; e'" |
---|
18 | with precedence 48 for @{'m_bind ${e} (λ${ident v}. ${e'})}. |
---|
19 | notation > "! ident v : ty ← e; e'" |
---|
20 | with precedence 48 for @{'m_bind ${e} (λ${ident v} : ${ty}. ${e'})}. |
---|
21 | notation < "vbox(! \nbsp ident v ← e ; break e')" |
---|
22 | with precedence 48 for @{'m_bind ${e} (λ${ident v}.${e'})}. |
---|
23 | notation > "! ident v ← e : ty ; e'" |
---|
24 | with precedence 48 for @{'m_bind (${e} : ${ty}) (λ${ident v}.${e'})}. |
---|
25 | notation < "vbox(! \nbsp ident v : ty \nbsp ← \nbsp e ; break e')" |
---|
26 | with precedence 48 for @{'m_bind ${e} (λ${ident v} : ${ty}. ${e'})}. |
---|
27 | notation > "! ident v : ty ← e : ty' ; e'" |
---|
28 | with precedence 48 for @{'m_bind (${e} : ${ty'}) (λ${ident v} : ${ty}. ${e'})}. |
---|
29 | notation > "! 〈ident v1, ident v2〉 ← e ; e'" |
---|
30 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1}. λ${ident v2}. ${e'})}. |
---|
31 | notation > "! 〈ident v1, ident v2〉 ← e : ty ; e'" |
---|
32 | with precedence 48 for @{'m_bind2 (${e} : $ty) (λ${ident v1}. λ${ident v2}. ${e'})}. |
---|
33 | notation > "! 〈ident v1 : ty1, ident v2 : ty2〉 ← e ; e'" |
---|
34 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. ${e'})}. |
---|
35 | notation < "vbox(! \nbsp 〈ident v1, ident v2〉 ← e ; break e')" |
---|
36 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1}. λ${ident v2}. ${e'})}. |
---|
37 | notation < "vbox(! \nbsp 〈ident v1 : ty1, ident v2 : ty2〉 \nbsp ← \nbsp e ; break e')" |
---|
38 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. ${e'})}. |
---|
39 | notation > "! 〈ident v1, ident v2, ident v3〉 ← e ; e'" |
---|
40 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1}. λ${ident v2}. λ${ident v3}. ${e'})}. |
---|
41 | notation > "! 〈ident v1, ident v2, ident v3〉 ← e : ty ; e'" |
---|
42 | with precedence 48 for @{'m_bind3 (${e} : ${ty}) (λ${ident v1}. λ${ident v2}. λ${ident v3}. ${e'})}. |
---|
43 | notation > "! 〈ident v1 : ty1, ident v2 : ty2, ident v3 : ty3〉 ← e ; e'" |
---|
44 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. λ${ident v3} : ${ty3}. ${e'})}. |
---|
45 | notation < "vbox(! \nbsp 〈ident v1, ident v2, ident v3〉 \nbsp ← \nbsp e ; break e')" |
---|
46 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1}. λ${ident v2}. λ${ident v3}. ${e'})}. |
---|
47 | notation < "vbox(! \nbsp 〈ident v1 : ty1, ident v2 : ty2, ident v3 : ty3〉 \nbsp ← e \nbsp ; break e')" |
---|
48 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. λ${ident v3} : ${ty3}. ${e'})}. |
---|
49 | |
---|
50 | (* dependent pair versions *) |
---|
51 | notation > "! «ident v1, ident v2» ← e ; e'" |
---|
52 | with precedence 48 for |
---|
53 | @{'m_bind ${e} (λ${fresh p_sig}. |
---|
54 | match ${fresh p_sig} with [mk_Sig ${ident v1} ${ident v2} ⇒ ${e'}])}. |
---|
55 | notation < "vbox(! \nbsp «ident v1, ident v2» \nbsp ← \nbsp e ; break e')" |
---|
56 | with precedence 48 for |
---|
57 | @{'m_bind ${e} (λ${fresh p_sig}. |
---|
58 | match ${fresh p_sig} with [mk_Sig ${ident v1} ${ident v2} ⇒ ${e'}])}. |
---|
59 | |
---|
60 | notation > "! «ident v1, ident v2, ident H» ← e ; e'" |
---|
61 | with precedence 48 for |
---|
62 | @{'m_sigbind2 ${e} (λ${ident v1},${ident v2},${ident H}. ${e'})}. |
---|
63 | notation < "vbox(! \nbsp «ident v1, ident v2, ident H» \nbsp ← \nbsp e ; e')" |
---|
64 | with precedence 48 for |
---|
65 | @{'m_sigbind2 ${e} (λ${ident v1} : ${ty1}.λ${ident v2} : ${ty2}. |
---|
66 | λ${ident H} : ${ty3}. ${e'})}. |
---|
67 | |
---|
68 | |
---|
69 | (*alternative do notation for backward compatibility *) |
---|
70 | notation > "'do'_ e; e'" |
---|
71 | with precedence 48 for @{'m_bind ${e} (λ_. ${e'})}. |
---|
72 | notation > "'do' ident v ← e; e'" |
---|
73 | with precedence 48 for @{'m_bind ${e} (λ${ident v}. ${e'})}. |
---|
74 | notation > "'do' ident v : ty ← e; e'" |
---|
75 | with precedence 48 for @{'m_bind ${e} (λ${ident v} : ${ty}. ${e'})}. |
---|
76 | notation > "'do' ident v ← e : ty ; e'" |
---|
77 | with precedence 48 for @{'m_bind (${e} : ${ty}) (λ${ident v}.${e'})}. |
---|
78 | notation > "'do' ident v : ty ← e : ty' ; e'" |
---|
79 | with precedence 48 for @{'m_bind (${e} : ${ty'}) (λ${ident v} : ${ty}. ${e'})}. |
---|
80 | notation > "'do' 〈ident v1, ident v2〉 ← e ; e'" |
---|
81 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1}. λ${ident v2}. ${e'})}. |
---|
82 | notation > "'do' 〈ident v1 : ty1, ident v2 : ty2〉 ← e ; e'" |
---|
83 | with precedence 48 for @{'m_bind2 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. ${e'})}. |
---|
84 | notation > "'do' 〈ident v1, ident v2, ident v3〉 ← e ; e'" |
---|
85 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1}. λ${ident v2}. λ${ident v3}. ${e'})}. |
---|
86 | notation > "'do' 〈ident v1 : ty1, ident v2 : ty2, ident v3 : ty3〉 ← e ; e'" |
---|
87 | with precedence 48 for @{'m_bind3 ${e} (λ${ident v1} : ${ty1}. λ${ident v2} : ${ty2}. λ${ident v3} : ${ty3}. ${e'})}. |
---|
88 | |
---|
89 | (* dependent pair versions *) |
---|
90 | notation > "'do' «ident v1, ident v2» ← e ; e'" |
---|
91 | with precedence 48 for |
---|
92 | @{'m_bind ${e} (λ${fresh p_sig}. |
---|
93 | match ${fresh p_sig} with [mk_Sig ${ident v1} ${ident v2} ⇒ ${e'}])}. |
---|
94 | |
---|
95 | notation > "'do' «ident v1, ident v2, ident H» ← e ; e'" |
---|
96 | with precedence 48 for |
---|
97 | @{'m_sigbind2 ${e} (λ${ident v1},${ident v2},${ident H}. ${e'})}. |
---|
98 | |
---|
99 | notation > "'return' t" with precedence 49 for @{'m_return $t}. |
---|
100 | notation < "'return' \nbsp t" with precedence 49 for @{'m_return $t}. |
---|
101 | |
---|
102 | interpretation "monad bind" 'm_bind m f = (m_bind ? ? ? m f). |
---|
103 | interpretation "monad return" 'm_return x = (m_return ? ? x). |
---|
104 | |
---|
105 | |
---|
106 | include "basics/lists/list.ma". |
---|
107 | |
---|
108 | |
---|
109 | (* add structure and properties as needed *) |
---|
110 | record Monad : Type[1] ≝ { |
---|
111 | m_def :> MonadDefinition ; |
---|
112 | m_map : ∀X, Y. (X → Y) → monad m_def X → monad m_def Y ; |
---|
113 | m_map2 : ∀X, Y, Z. (X → Y → Z) → |
---|
114 | monad m_def X → monad m_def Y → monad m_def Z; |
---|
115 | m_bind2 : ∀X,Y,Z.monad m_def (X×Y) → (X → Y → monad m_def Z) → monad m_def Z; |
---|
116 | m_bind3 : ∀X,Y,Z,W.monad m_def (X×Y×Z) → (X → Y → Z → monad m_def W) → monad m_def W; |
---|
117 | m_join : ∀X.monad m_def (monad m_def X) → monad m_def X; |
---|
118 | m_sigbind2 : ∀A,B,C.∀P:A×B → Prop. monad m_def (Σx:A×B.P x) → |
---|
119 | (∀a,b. P 〈a,b〉 → monad m_def C) → monad m_def C; |
---|
120 | m_mmap : ∀X,Y.(X → monad m_def Y) → list X → monad m_def (list Y); |
---|
121 | m_mmap_sigma : ∀X,Y,P.(X → monad m_def (Σy : Y.P y)) → list X → monad m_def (Σl : list Y.All ? P l) |
---|
122 | }. |
---|
123 | |
---|
124 | interpretation "monad bind2" 'm_bind2 m f = (m_bind2 ? ? ? ? m f). |
---|
125 | interpretation "monad bind3" 'm_bind3 m f = (m_bind3 ? ? ? ? ? m f). |
---|
126 | interpretation "monad sigbind2" 'm_sigbind2 m f = (m_sigbind2 ????? m f). |
---|
127 | |
---|
128 | (* |
---|
129 | check (λM : Monad.λA,B,C,P.λp.λf : ∀a,b.P 〈a,b〉 → monad M C.! «a,b,H» ← p; f a b H) |
---|
130 | *) |
---|
131 | |
---|
132 | record MonadProps : Type[1] ≝ |
---|
133 | { max_def :> Monad |
---|
134 | ; m_return_bind : ∀X,Y.∀x : X.∀f : X → monad max_def Y. ! y ← return x ; f y = f x |
---|
135 | ; m_bind_return : ∀X.∀m : monad max_def X.! x ← m ; return x = m |
---|
136 | ; m_bind_bind : ∀X,Y,Z. ∀m : monad max_def X.∀f : X → monad max_def Y. |
---|
137 | ∀g : Y → monad max_def Z.! y ← (! x ← m ; f x) ; g y = ! x ← m; ! y ← f x ; g y |
---|
138 | }. |
---|
139 | |
---|
140 | record SetoidMonadProps : Type[1] ≝ |
---|
141 | { smax_def :> Monad |
---|
142 | ; sm_eq : ∀X.relation (monad smax_def X) |
---|
143 | ; sm_eq_refl : ∀X.reflexive ? (sm_eq X) |
---|
144 | ; sm_eq_trans : ∀X.transitive ? (sm_eq X) |
---|
145 | ; sm_eq_sym : ∀X.symmetric ? (sm_eq X) |
---|
146 | ; sm_return_proper : ∀X .m_return smax_def X ⊨ eq ? ++> sm_eq ? |
---|
147 | ; sm_bind_proper : ∀X, Y.m_bind smax_def X Y ⊨ sm_eq ? ++> (eq ? ++> sm_eq ?) ++> sm_eq ? |
---|
148 | ; sm_return_bind : ∀X,Y.∀x : X.∀f : X → monad smax_def Y. |
---|
149 | sm_eq Y (! y ← return x ; f y) (f x) |
---|
150 | ; sm_bind_return : ∀X.∀m : monad smax_def X.sm_eq X (! x ← m ; return x) m |
---|
151 | ; sm_bind_bind : ∀X,Y,Z. ∀m : monad smax_def X.∀f : X → monad smax_def Y. |
---|
152 | ∀g : Y → monad smax_def Z.sm_eq Z (! y ← (! x ← m ; f x) ; g y) (! x ← m; ! y ← f x ; g y) |
---|
153 | }. |
---|
154 | |
---|
155 | interpretation "monad setoid equality" 'std_eq x y = (sm_eq ?? x y). |
---|
156 | |
---|
157 | |
---|
158 | definition MakeMonad : ?→?→?→Monad ≝ λmonad,m_return,m_bind. |
---|
159 | mk_Monad (mk_MonadDefinition monad m_return m_bind) |
---|
160 | (* map *) |
---|
161 | (λX,Y,f,m. |
---|
162 | ! x ← m ; |
---|
163 | return f x) |
---|
164 | (* map2 *) |
---|
165 | (λX,Y,Z,f,m,n. |
---|
166 | ! x ← m ; |
---|
167 | ! y ← n ; |
---|
168 | return (f x y)) |
---|
169 | (* bind2 *) |
---|
170 | (λX,Y,Z,m,f. |
---|
171 | ! p ← m ; |
---|
172 | let 〈x, y〉 ≝ p in |
---|
173 | f x y) |
---|
174 | (λX,Y,Z,W,m,f. |
---|
175 | ! p ← m ; |
---|
176 | let 〈x, y, z〉 ≝ p in |
---|
177 | f x y z) |
---|
178 | (* join *) |
---|
179 | (λX,m.! x ← m ; x) |
---|
180 | (* m_sigbind2 *) |
---|
181 | (λA,B,C,P,e,f. |
---|
182 | ! e_sig ← e ; |
---|
183 | match e_sig with |
---|
184 | [ mk_Sig p p_prf ⇒ |
---|
185 | match p return λx.x = p → ? with |
---|
186 | [ mk_Prod a b ⇒ |
---|
187 | λeq_p. f a b (eq_ind_r ?? (λx.λ_.P x) p_prf ? eq_p) |
---|
188 | ](refl …) |
---|
189 | ]) |
---|
190 | (λX,Y,f,l.foldr … (λel,macc.! r ← f el; !acc ← macc; return (r :: acc)) (return [ ]) l) |
---|
191 | (λX,Y,P,f,l.foldr … (λel,macc. |
---|
192 | ! «r, r_prf» ← f el ; |
---|
193 | ! «acc, acc_prf» ← macc ; |
---|
194 | return (mk_Sig ?? (r :: acc) ?)) |
---|
195 | (return (mk_Sig … [ ] ?)) l). |
---|
196 | % assumption qed. |
---|
197 | |
---|
198 | definition MakeMonadProps : ?→?→?→?→?→?→MonadProps ≝ λmonad,m_return,m_bind,p1,p2,p3. |
---|
199 | mk_MonadProps (MakeMonad monad m_return m_bind) p1 p2 p3. |
---|
200 | |
---|
201 | definition MakeSetoidMonadProps : ?→?→?→?→?→?→?→?→?→?→?→?→SetoidMonadProps ≝ |
---|
202 | λmonad,m_return,m_bind,sm_eq,p1,p2,p3,p4,p5,p6,p7,p8. |
---|
203 | mk_SetoidMonadProps (MakeMonad monad m_return m_bind) sm_eq p1 p2 p3 p4 p5 p6 p7 p8. |
---|