21 infixr 5 @|; |
21 infixr 5 @|; |
22 |
22 |
23 |
23 |
24 (** Haskell serializer **) |
24 (** Haskell serializer **) |
25 |
25 |
26 fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const |
26 fun print_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const |
27 reserved deresolve contr_classparam_typs deriving_show = |
27 reserved deresolve contr_classparam_typs deriving_show = |
28 let |
28 let |
29 val deresolve_base = Long_Name.base_name o deresolve; |
29 val deresolve_base = Long_Name.base_name o deresolve; |
30 fun class_name class = case syntax_class class |
30 fun class_name class = case syntax_class class |
31 of NONE => deresolve class |
31 of NONE => deresolve class |
32 | SOME class => class; |
32 | SOME class => class; |
33 fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs |
33 fun print_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs |
34 of [] => [] |
34 of [] => [] |
35 | classbinds => Pretty.enum "," "(" ")" ( |
35 | classbinds => Pretty.list "(" ")" ( |
36 map (fn (v, class) => |
36 map (fn (v, class) => |
37 str (class_name class ^ " " ^ lookup_var tyvars v)) classbinds) |
37 str (class_name class ^ " " ^ lookup_var tyvars v)) classbinds) |
38 @@ str " => "; |
38 @@ str " => "; |
39 fun pr_typforall tyvars vs = case map fst vs |
39 fun print_typforall tyvars vs = case map fst vs |
40 of [] => [] |
40 of [] => [] |
41 | vnames => str "forall " :: Pretty.breaks |
41 | vnames => str "forall " :: Pretty.breaks |
42 (map (str o lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1; |
42 (map (str o lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1; |
43 fun pr_tycoexpr tyvars fxy (tyco, tys) = |
43 fun print_tyco_expr tyvars fxy (tyco, tys) = |
44 brackify fxy (str tyco :: map (pr_typ tyvars BR) tys) |
44 brackify fxy (str tyco :: map (print_typ tyvars BR) tys) |
45 and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco |
45 and print_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco |
46 of NONE => pr_tycoexpr tyvars fxy (deresolve tyco, tys) |
46 of NONE => print_tyco_expr tyvars fxy (deresolve tyco, tys) |
47 | SOME (i, pr) => pr (pr_typ tyvars) fxy tys) |
47 | SOME (i, print) => print (print_typ tyvars) fxy tys) |
48 | pr_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v; |
48 | print_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v; |
49 fun pr_typdecl tyvars (vs, tycoexpr) = |
49 fun print_typdecl tyvars (vs, tycoexpr) = |
50 Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr); |
50 Pretty.block (print_typcontext tyvars vs @| print_tyco_expr tyvars NOBR tycoexpr); |
51 fun pr_typscheme tyvars (vs, ty) = |
51 fun print_typscheme tyvars (vs, ty) = |
52 Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty); |
52 Pretty.block (print_typforall tyvars vs @ print_typcontext tyvars vs @| print_typ tyvars NOBR ty); |
53 fun pr_term tyvars thm vars fxy (IConst c) = |
53 fun print_term tyvars thm vars fxy (IConst c) = |
54 pr_app tyvars thm vars fxy (c, []) |
54 print_app tyvars thm vars fxy (c, []) |
55 | pr_term tyvars thm vars fxy (t as (t1 `$ t2)) = |
55 | print_term tyvars thm vars fxy (t as (t1 `$ t2)) = |
56 (case Code_Thingol.unfold_const_app t |
56 (case Code_Thingol.unfold_const_app t |
57 of SOME app => pr_app tyvars thm vars fxy app |
57 of SOME app => print_app tyvars thm vars fxy app |
58 | _ => |
58 | _ => |
59 brackify fxy [ |
59 brackify fxy [ |
60 pr_term tyvars thm vars NOBR t1, |
60 print_term tyvars thm vars NOBR t1, |
61 pr_term tyvars thm vars BR t2 |
61 print_term tyvars thm vars BR t2 |
62 ]) |
62 ]) |
63 | pr_term tyvars thm vars fxy (IVar NONE) = |
63 | print_term tyvars thm vars fxy (IVar NONE) = |
64 str "_" |
64 str "_" |
65 | pr_term tyvars thm vars fxy (IVar (SOME v)) = |
65 | print_term tyvars thm vars fxy (IVar (SOME v)) = |
66 (str o lookup_var vars) v |
66 (str o lookup_var vars) v |
67 | pr_term tyvars thm vars fxy (t as _ `|=> _) = |
67 | print_term tyvars thm vars fxy (t as _ `|=> _) = |
68 let |
68 let |
69 val (binds, t') = Code_Thingol.unfold_pat_abs t; |
69 val (binds, t') = Code_Thingol.unfold_pat_abs t; |
70 val (ps, vars') = fold_map (pr_bind tyvars thm BR o fst) binds vars; |
70 val (ps, vars') = fold_map (print_bind tyvars thm BR o fst) binds vars; |
71 in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars thm vars' NOBR t') end |
71 in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars thm vars' NOBR t') end |
72 | pr_term tyvars thm vars fxy (ICase (cases as (_, t0))) = |
72 | print_term tyvars thm vars fxy (ICase (cases as (_, t0))) = |
73 (case Code_Thingol.unfold_const_app t0 |
73 (case Code_Thingol.unfold_const_app t0 |
74 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
74 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
75 then pr_case tyvars thm vars fxy cases |
75 then print_case tyvars thm vars fxy cases |
76 else pr_app tyvars thm vars fxy c_ts |
76 else print_app tyvars thm vars fxy c_ts |
77 | NONE => pr_case tyvars thm vars fxy cases) |
77 | NONE => print_case tyvars thm vars fxy cases) |
78 and pr_app' tyvars thm vars ((c, (_, tys)), ts) = case contr_classparam_typs c |
78 and print_app_expr tyvars thm vars ((c, (_, tys)), ts) = case contr_classparam_typs c |
79 of [] => (str o deresolve) c :: map (pr_term tyvars thm vars BR) ts |
79 of [] => (str o deresolve) c :: map (print_term tyvars thm vars BR) ts |
80 | fingerprint => let |
80 | fingerprint => let |
81 val ts_fingerprint = ts ~~ curry Library.take (length ts) fingerprint; |
81 val ts_fingerprint = ts ~~ curry Library.take (length ts) fingerprint; |
82 val needs_annotation = forall (fn (_, NONE) => true | (t, SOME _) => |
82 val needs_annotation = forall (fn (_, NONE) => true | (t, SOME _) => |
83 (not o Code_Thingol.locally_monomorphic) t) ts_fingerprint; |
83 (not o Code_Thingol.locally_monomorphic) t) ts_fingerprint; |
84 fun pr_term_anno (t, NONE) _ = pr_term tyvars thm vars BR t |
84 fun print_term_anno (t, NONE) _ = print_term tyvars thm vars BR t |
85 | pr_term_anno (t, SOME _) ty = |
85 | print_term_anno (t, SOME _) ty = |
86 brackets [pr_term tyvars thm vars NOBR t, str "::", pr_typ tyvars NOBR ty]; |
86 brackets [print_term tyvars thm vars NOBR t, str "::", print_typ tyvars NOBR ty]; |
87 in |
87 in |
88 if needs_annotation then |
88 if needs_annotation then |
89 (str o deresolve) c :: map2 pr_term_anno ts_fingerprint (curry Library.take (length ts) tys) |
89 (str o deresolve) c :: map2 print_term_anno ts_fingerprint (curry Library.take (length ts) tys) |
90 else (str o deresolve) c :: map (pr_term tyvars thm vars BR) ts |
90 else (str o deresolve) c :: map (print_term tyvars thm vars BR) ts |
91 end |
91 end |
92 and pr_app tyvars = gen_pr_app (pr_app' tyvars) (pr_term tyvars) syntax_const |
92 and print_app tyvars = gen_print_app (print_app_expr tyvars) (print_term tyvars) syntax_const |
93 and pr_bind tyvars thm fxy p = gen_pr_bind (pr_term tyvars) thm fxy p |
93 and print_bind tyvars thm fxy p = gen_print_bind (print_term tyvars) thm fxy p |
94 and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) = |
94 and print_case tyvars thm vars fxy (cases as ((_, [_]), _)) = |
95 let |
95 let |
96 val (binds, body) = Code_Thingol.unfold_let (ICase cases); |
96 val (binds, body) = Code_Thingol.unfold_let (ICase cases); |
97 fun pr ((pat, ty), t) vars = |
97 fun print_match ((pat, ty), t) vars = |
98 vars |
98 vars |
99 |> pr_bind tyvars thm BR pat |
99 |> print_bind tyvars thm BR pat |
100 |>> (fn p => semicolon [p, str "=", pr_term tyvars thm vars NOBR t]) |
100 |>> (fn p => semicolon [p, str "=", print_term tyvars thm vars NOBR t]) |
101 val (ps, vars') = fold_map pr binds vars; |
101 val (ps, vars') = fold_map print_match binds vars; |
102 in brackify_block fxy (str "let {") |
102 in brackify_block fxy (str "let {") |
103 ps |
103 ps |
104 (concat [str "}", str "in", pr_term tyvars thm vars' NOBR body]) |
104 (concat [str "}", str "in", print_term tyvars thm vars' NOBR body]) |
105 end |
105 end |
106 | pr_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) = |
106 | print_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) = |
107 let |
107 let |
108 fun pr (pat, body) = |
108 fun print_select (pat, body) = |
109 let |
109 let |
110 val (p, vars') = pr_bind tyvars thm NOBR pat vars; |
110 val (p, vars') = print_bind tyvars thm NOBR pat vars; |
111 in semicolon [p, str "->", pr_term tyvars thm vars' NOBR body] end; |
111 in semicolon [p, str "->", print_term tyvars thm vars' NOBR body] end; |
112 in brackify_block fxy |
112 in brackify_block fxy |
113 (concat [str "case", pr_term tyvars thm vars NOBR t, str "of", str "{"]) |
113 (concat [str "case", print_term tyvars thm vars NOBR t, str "of", str "{"]) |
114 (map pr clauses) |
114 (map print_select clauses) |
115 (str "}") |
115 (str "}") |
116 end |
116 end |
117 | pr_case tyvars thm vars fxy ((_, []), _) = |
117 | print_case tyvars thm vars fxy ((_, []), _) = |
118 (brackify fxy o Pretty.breaks o map str) ["error", "\"empty case\""]; |
118 (brackify fxy o Pretty.breaks o map str) ["error", "\"empty case\""]; |
119 fun pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) = |
119 fun print_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) = |
120 let |
120 let |
121 val tyvars = intro_vars (map fst vs) reserved; |
121 val tyvars = intro_vars (map fst vs) reserved; |
122 val n = (length o fst o Code_Thingol.unfold_fun) ty; |
122 val n = (length o fst o Code_Thingol.unfold_fun) ty; |
123 in |
123 in |
124 Pretty.chunks [ |
124 Pretty.chunks [ |
125 Pretty.block [ |
125 semicolon [ |
126 (str o suffix " ::" o deresolve_base) name, |
126 (str o suffix " ::" o deresolve_base) name, |
127 Pretty.brk 1, |
127 print_typscheme tyvars (vs, ty) |
128 pr_typscheme tyvars (vs, ty), |
|
129 str ";" |
|
130 ], |
128 ], |
131 concat ( |
129 semicolon ( |
132 (str o deresolve_base) name |
130 (str o deresolve_base) name |
133 :: map str (replicate n "_") |
131 :: map str (replicate n "_") |
134 @ str "=" |
132 @ str "=" |
135 :: str "error" |
133 :: str "error" |
136 @@ (str o (fn s => s ^ ";") o ML_Syntax.print_string |
134 @@ (str o ML_Syntax.print_string |
137 o Long_Name.base_name o Long_Name.qualifier) name |
135 o Long_Name.base_name o Long_Name.qualifier) name |
138 ) |
136 ) |
139 ] |
137 ] |
140 end |
138 end |
141 | pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) = |
139 | print_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) = |
142 let |
140 let |
143 val eqs = filter (snd o snd) raw_eqs; |
141 val eqs = filter (snd o snd) raw_eqs; |
144 val tyvars = intro_vars (map fst vs) reserved; |
142 val tyvars = intro_vars (map fst vs) reserved; |
145 fun pr_eq ((ts, t), (thm, _)) = |
143 fun print_eqn ((ts, t), (thm, _)) = |
146 let |
144 let |
147 val consts = fold Code_Thingol.add_constnames (t :: ts) []; |
145 val consts = fold Code_Thingol.add_constnames (t :: ts) []; |
148 val vars = reserved |
146 val vars = reserved |
149 |> intro_base_names |
147 |> intro_base_names |
150 (is_none o syntax_const) deresolve consts |
148 (is_none o syntax_const) deresolve consts |
151 |> intro_vars ((fold o Code_Thingol.fold_varnames) |
149 |> intro_vars ((fold o Code_Thingol.fold_varnames) |
152 (insert (op =)) ts []); |
150 (insert (op =)) ts []); |
153 in |
151 in |
154 semicolon ( |
152 semicolon ( |
155 (str o deresolve_base) name |
153 (str o deresolve_base) name |
156 :: map (pr_term tyvars thm vars BR) ts |
154 :: map (print_term tyvars thm vars BR) ts |
157 @ str "=" |
155 @ str "=" |
158 @@ pr_term tyvars thm vars NOBR t |
156 @@ print_term tyvars thm vars NOBR t |
159 ) |
157 ) |
160 end; |
158 end; |
161 in |
159 in |
162 Pretty.chunks ( |
160 Pretty.chunks ( |
163 Pretty.block [ |
161 semicolon [ |
164 (str o suffix " ::" o deresolve_base) name, |
162 (str o suffix " ::" o deresolve_base) name, |
165 Pretty.brk 1, |
163 print_typscheme tyvars (vs, ty) |
166 pr_typscheme tyvars (vs, ty), |
|
167 str ";" |
|
168 ] |
164 ] |
169 :: map pr_eq eqs |
165 :: map print_eqn eqs |
170 ) |
166 ) |
171 end |
167 end |
172 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, []))) = |
168 | print_stmt (name, Code_Thingol.Datatype (_, (vs, []))) = |
173 let |
169 let |
174 val tyvars = intro_vars (map fst vs) reserved; |
170 val tyvars = intro_vars (map fst vs) reserved; |
175 in |
171 in |
176 semicolon [ |
172 semicolon [ |
177 str "data", |
173 str "data", |
178 pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
174 print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
179 ] |
175 ] |
180 end |
176 end |
181 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) = |
177 | print_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) = |
182 let |
178 let |
183 val tyvars = intro_vars (map fst vs) reserved; |
179 val tyvars = intro_vars (map fst vs) reserved; |
184 in |
180 in |
185 semicolon ( |
181 semicolon ( |
186 str "newtype" |
182 str "newtype" |
187 :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
183 :: print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
188 :: str "=" |
184 :: str "=" |
189 :: (str o deresolve_base) co |
185 :: (str o deresolve_base) co |
190 :: pr_typ tyvars BR ty |
186 :: print_typ tyvars BR ty |
191 :: (if deriving_show name then [str "deriving (Read, Show)"] else []) |
187 :: (if deriving_show name then [str "deriving (Read, Show)"] else []) |
192 ) |
188 ) |
193 end |
189 end |
194 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) = |
190 | print_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) = |
195 let |
191 let |
196 val tyvars = intro_vars (map fst vs) reserved; |
192 val tyvars = intro_vars (map fst vs) reserved; |
197 fun pr_co (co, tys) = |
193 fun print_co (co, tys) = |
198 concat ( |
194 concat ( |
199 (str o deresolve_base) co |
195 (str o deresolve_base) co |
200 :: map (pr_typ tyvars BR) tys |
196 :: map (print_typ tyvars BR) tys |
201 ) |
197 ) |
202 in |
198 in |
203 semicolon ( |
199 semicolon ( |
204 str "data" |
200 str "data" |
205 :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
201 :: print_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
206 :: str "=" |
202 :: str "=" |
207 :: pr_co co |
203 :: print_co co |
208 :: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos |
204 :: map ((fn p => Pretty.block [str "| ", p]) o print_co) cos |
209 @ (if deriving_show name then [str "deriving (Read, Show)"] else []) |
205 @ (if deriving_show name then [str "deriving (Read, Show)"] else []) |
210 ) |
206 ) |
211 end |
207 end |
212 | pr_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) = |
208 | print_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) = |
213 let |
209 let |
214 val tyvars = intro_vars [v] reserved; |
210 val tyvars = intro_vars [v] reserved; |
215 fun pr_classparam (classparam, ty) = |
211 fun print_classparam (classparam, ty) = |
216 semicolon [ |
212 semicolon [ |
217 (str o deresolve_base) classparam, |
213 (str o deresolve_base) classparam, |
218 str "::", |
214 str "::", |
219 pr_typ tyvars NOBR ty |
215 print_typ tyvars NOBR ty |
220 ] |
216 ] |
221 in |
217 in |
222 Pretty.block_enclose ( |
218 Pretty.block_enclose ( |
223 Pretty.block [ |
219 Pretty.block [ |
224 str "class ", |
220 str "class ", |
225 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]), |
221 Pretty.block (print_typcontext tyvars [(v, map fst superclasses)]), |
226 str (deresolve_base name ^ " " ^ lookup_var tyvars v), |
222 str (deresolve_base name ^ " " ^ lookup_var tyvars v), |
227 str " where {" |
223 str " where {" |
228 ], |
224 ], |
229 str "};" |
225 str "};" |
230 ) (map pr_classparam classparams) |
226 ) (map print_classparam classparams) |
231 end |
227 end |
232 | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
228 | print_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
233 let |
229 let |
234 val tyvars = intro_vars (map fst vs) reserved; |
230 val tyvars = intro_vars (map fst vs) reserved; |
235 fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
231 fun print_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
236 of NONE => semicolon [ |
232 of NONE => semicolon [ |
237 (str o deresolve_base) classparam, |
233 (str o deresolve_base) classparam, |
238 str "=", |
234 str "=", |
239 pr_app tyvars thm reserved NOBR (c_inst, []) |
235 print_app tyvars thm reserved NOBR (c_inst, []) |
240 ] |
236 ] |
241 | SOME (k, pr) => |
237 | SOME (k, pr) => |
242 let |
238 let |
243 val (c_inst_name, (_, tys)) = c_inst; |
239 val (c_inst_name, (_, tys)) = c_inst; |
244 val const = if (is_some o syntax_const) c_inst_name |
240 val const = if (is_some o syntax_const) c_inst_name |
441 | dest_monad _ t = case Code_Thingol.split_let t |
434 | dest_monad _ t = case Code_Thingol.split_let t |
442 of SOME (((pat, ty), tbind), t') => |
435 of SOME (((pat, ty), tbind), t') => |
443 SOME ((SOME ((pat, ty), false), tbind), t') |
436 SOME ((SOME ((pat, ty), false), tbind), t') |
444 | NONE => NONE; |
437 | NONE => NONE; |
445 fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name); |
438 fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name); |
446 fun pr_monad pr_bind pr (NONE, t) vars = |
439 fun print_monad print_bind print_term (NONE, t) vars = |
447 (semicolon [pr vars NOBR t], vars) |
440 (semicolon [print_term vars NOBR t], vars) |
448 | pr_monad pr_bind pr (SOME ((bind, _), true), t) vars = vars |
441 | print_monad print_bind print_term (SOME ((bind, _), true), t) vars = vars |
449 |> pr_bind NOBR bind |
442 |> print_bind NOBR bind |
450 |>> (fn p => semicolon [p, str "<-", pr vars NOBR t]) |
443 |>> (fn p => semicolon [p, str "<-", print_term vars NOBR t]) |
451 | pr_monad pr_bind pr (SOME ((bind, _), false), t) vars = vars |
444 | print_monad print_bind print_term (SOME ((bind, _), false), t) vars = vars |
452 |> pr_bind NOBR bind |
445 |> print_bind NOBR bind |
453 |>> (fn p => semicolon [str "let", p, str "=", pr vars NOBR t]); |
446 |>> (fn p => semicolon [str "let", p, str "=", print_term vars NOBR t]); |
454 fun pretty _ [c_bind'] pr thm vars fxy [(t1, _), (t2, _)] = case dest_bind t1 t2 |
447 fun pretty _ [c_bind'] print_term thm vars fxy [(t1, _), (t2, _)] = case dest_bind t1 t2 |
455 of SOME (bind, t') => let |
448 of SOME (bind, t') => let |
456 val (binds, t'') = implode_monad c_bind' t' |
449 val (binds, t'') = implode_monad c_bind' t' |
457 val (ps, vars') = fold_map (pr_monad (gen_pr_bind (K pr) thm) pr) (bind :: binds) vars; |
450 val (ps, vars') = fold_map (print_monad (gen_print_bind (K print_term) thm) print_term) |
458 in (brackify fxy o single o Pretty.enclose "do {" "}" o Pretty.breaks) (ps @| pr vars' NOBR t'') end |
451 (bind :: binds) vars; |
|
452 in |
|
453 (brackify fxy o single o Pretty.enclose "do {" "}" o Pretty.breaks) |
|
454 (ps @| print_term vars' NOBR t'') |
|
455 end |
459 | NONE => brackify_infix (1, L) fxy |
456 | NONE => brackify_infix (1, L) fxy |
460 [pr vars (INFX (1, L)) t1, str ">>=", pr vars (INFX (1, X)) t2] |
457 [print_term vars (INFX (1, L)) t1, str ">>=", print_term vars (INFX (1, X)) t2] |
461 in (2, ([c_bind], pretty)) end; |
458 in (2, ([c_bind], pretty)) end; |
462 |
459 |
463 fun add_monad target' raw_c_bind thy = |
460 fun add_monad target' raw_c_bind thy = |
464 let |
461 let |
465 val c_bind = Code.read_const thy raw_c_bind; |
462 val c_bind = Code.read_const thy raw_c_bind; |