Prepare ADT generator for new error monad

This commit is contained in:
Suzanne Dupéron 2020-04-16 17:31:38 +02:00
parent a0b450a34d
commit 12cbc9ca07
2 changed files with 28 additions and 28 deletions

View File

@ -143,7 +143,7 @@ say "";
for $statements -> $statement { for $statements -> $statement {
say "$statement" say "$statement"
} }
say "type 'a monad = 'a Simple_utils.Trace.result;;"; say "type ('a,'err) monad = ('a) Simple_utils.Trace.result;;";
say "let (>>?) v f = Simple_utils.Trace.bind f v;;"; say "let (>>?) v f = Simple_utils.Trace.bind f v;;";
say "let return v = Simple_utils.Trace.ok v;;"; say "let return v = Simple_utils.Trace.ok v;;";
say "open $moduleName;;"; say "open $moduleName;;";
@ -151,7 +151,7 @@ say "open $moduleName;;";
say ""; say "";
say "(* must be provided by one of the open or include statements: *)"; say "(* must be provided by one of the open or include statements: *)";
for $adts.grep({$_<kind> ne $record && $_<kind> ne $variant}).map({$_<kind>}).unique -> $poly for $adts.grep({$_<kind> ne $record && $_<kind> ne $variant}).map({$_<kind>}).unique -> $poly
{ say "let fold_map__$poly : type a new_a state . (state -> a -> (state * new_a) Simple_utils.Trace.result) -> state -> a $poly -> (state * new_a $poly) Simple_utils.Trace.result = fold_map__$poly;;"; } { say "let fold_map__$poly : type a new_a state . (state -> a -> (state * new_a, _) monad) -> state -> a $poly -> (state * new_a $poly , _) monad = fold_map__$poly;;"; }
say ""; say "";
for $adts.kv -> $index, $t { for $adts.kv -> $index, $t {
@ -182,34 +182,34 @@ say ";;";
say ""; say "";
for $adts.list -> $t { for $adts.list -> $t {
say "type 'state continue_fold_map__$t<name> = \{"; say "type ('state, 'err) continue_fold_map__$t<name> = \{";
say " node__$t<name> : 'state -> $t<name> -> ('state * $t<newName>) monad ;"; say " node__$t<name> : 'state -> $t<name> -> ('state * $t<newName> , 'err) monad ;";
for $t<ctorsOrFields>.list -> $c for $t<ctorsOrFields>.list -> $c
{ say " $t<name>__$c<name> : 'state -> {$c<type> || 'unit'} -> ('state * {$c<newType> || 'unit'}) monad ;" } { say " $t<name>__$c<name> : 'state -> {$c<type> || 'unit'} -> ('state * {$c<newType> || 'unit'} , 'err) monad ;" }
say ' };;'; say ' };;';
} }
say "type 'state continue_fold_map = \{"; say "type ('state , 'err) continue_fold_map = \{";
for $adts.list -> $t { for $adts.list -> $t {
say " $t<name> : 'state continue_fold_map__$t<name> ;"; say " $t<name> : ('state , 'err) continue_fold_map__$t<name> ;";
} }
say ' };;'; say ' };;';
say ""; say "";
for $adts.list -> $t for $adts.list -> $t
{ say "type 'state fold_map_config__$t<name> = \{"; { say "type ('state , 'err) fold_map_config__$t<name> = \{";
say " node__$t<name> : 'state -> $t<name> -> 'state continue_fold_map -> ('state * $t<newName>) monad ;"; # (*Adt_info.node_instance_info ->*) say " node__$t<name> : 'state -> $t<name> -> ('state, 'err) continue_fold_map -> ('state * $t<newName> , 'err) monad ;"; # (*Adt_info.node_instance_info ->*)
say " node__$t<name>__pre_state : 'state -> $t<name> -> 'state monad ;"; # (*Adt_info.node_instance_info ->*) say " node__$t<name>__pre_state : 'state -> $t<name> -> ('state, 'err) monad ;"; # (*Adt_info.node_instance_info ->*)
say " node__$t<name>__post_state : 'state -> $t<name> -> $t<newName> -> 'state monad ;"; # (*Adt_info.node_instance_info ->*) say " node__$t<name>__post_state : 'state -> $t<name> -> $t<newName> -> ('state, 'err) monad ;"; # (*Adt_info.node_instance_info ->*)
for $t<ctorsOrFields>.list -> $c for $t<ctorsOrFields>.list -> $c
{ say " $t<name>__$c<name> : 'state -> {$c<type> || 'unit'} -> 'state continue_fold_map -> ('state * {$c<newType> || 'unit'}) monad ;"; # (*Adt_info.ctor_or_field_instance_info ->*) { say " $t<name>__$c<name> : 'state -> {$c<type> || 'unit'} -> ('state, 'err) continue_fold_map -> ('state * {$c<newType> || 'unit'} , 'err) monad ;"; # (*Adt_info.ctor_or_field_instance_info ->*)
} }
say '};;' } say '};;' }
say "type 'state fold_map_config ="; say "type ('state, 'err) fold_map_config =";
say ' {'; say ' {';
for $adts.list -> $t for $adts.list -> $t
{ say " $t<name> : 'state fold_map_config__$t<name>;" } { say " $t<name> : ('state, 'err) fold_map_config__$t<name>;" }
say ' };;'; say ' };;';
say ""; say "";
@ -371,31 +371,31 @@ for $adts.list -> $t
say ""; say "";
say "type 'state mk_continue_fold_map = \{"; say "type ('state, 'err) mk_continue_fold_map = \{";
say " fn : 'state mk_continue_fold_map -> 'state fold_map_config -> 'state continue_fold_map"; say " fn : ('state,'err) mk_continue_fold_map -> ('state, 'err) fold_map_config -> ('state , 'err) continue_fold_map";
say '};;'; say '};;';
# fold_map functions # fold_map functions
say ""; say "";
for $adts.list -> $t for $adts.list -> $t
{ say "let _fold_map__$t<name> : type qstate . qstate mk_continue_fold_map -> qstate fold_map_config -> qstate -> $t<name> -> (qstate * $t<newName>) monad = fun mk_continue_fold_map visitor state x ->"; { say "let _fold_map__$t<name> : type qstate err . (qstate,err) mk_continue_fold_map -> (qstate,err) fold_map_config -> qstate -> $t<name> -> (qstate * $t<newName>, err) monad = fun mk_continue_fold_map visitor state x ->";
say " let continue_fold_map : qstate continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in"; say " let continue_fold_map : (qstate,err) continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in";
say " visitor.$t<name>.node__$t<name>__pre_state state x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*) say " visitor.$t<name>.node__$t<name>__pre_state state x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*)
say " visitor.$t<name>.node__$t<name> state x continue_fold_map >>? fun (state, new_x) ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*) say " visitor.$t<name>.node__$t<name> state x continue_fold_map >>? fun (state, new_x) ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*)
say " visitor.$t<name>.node__$t<name>__post_state state x new_x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*) say " visitor.$t<name>.node__$t<name>__post_state state x new_x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t<name>)*)
say " return (state, new_x);;"; say " return (state, new_x);;";
say ""; say "";
for $t<ctorsOrFields>.list -> $c for $t<ctorsOrFields>.list -> $c
{ say "let _fold_map__$t<name>__$c<name> : type qstate . qstate mk_continue_fold_map -> qstate fold_map_config -> qstate -> { $c<type> || 'unit' } -> (qstate * { $c<newType> || 'unit' }) monad = fun mk_continue_fold_map visitor state x ->"; { say "let _fold_map__$t<name>__$c<name> : type qstate err . (qstate,err) mk_continue_fold_map -> (qstate,err) fold_map_config -> qstate -> { $c<type> || 'unit' } -> (qstate * { $c<newType> || 'unit' }, err) monad = fun mk_continue_fold_map visitor state x ->";
say " let continue_fold_map : qstate continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in"; say " let continue_fold_map : (qstate,err) continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in";
say " visitor.$t<name>.$t<name>__$c<name> state x continue_fold_map;;"; # (*(fun () -> whole_adt_info, info__$t<name>, info__$t<name>__$c<name>)*) say " visitor.$t<name>.$t<name>__$c<name> state x continue_fold_map;;"; # (*(fun () -> whole_adt_info, info__$t<name>, info__$t<name>__$c<name>)*)
say ""; } } say ""; } }
# make the "continue" object # make the "continue" object
say ""; say "";
say '(* Curries the "visitor" argument to the folds (non-customizable traversal functions). *)'; say '(* Curries the "visitor" argument to the folds (non-customizable traversal functions). *)';
say "let mk_continue_fold_map : 'state . 'state mk_continue_fold_map = \{ fn = fun self visitor ->"; say "let mk_continue_fold_map : 'state 'err . ('state,'err) mk_continue_fold_map = \{ fn = fun self visitor ->";
say ' {'; say ' {';
for $adts.list -> $t for $adts.list -> $t
{ say " $t<name> = \{"; { say " $t<name> = \{";
@ -410,16 +410,16 @@ say "";
# fold_map functions : tying the knot # fold_map functions : tying the knot
say ""; say "";
for $adts.list -> $t for $adts.list -> $t
{ say "let fold_map__$t<name> : type qstate . qstate fold_map_config -> qstate -> $t<name> -> (qstate * $t<newName>) monad ="; { say "let fold_map__$t<name> : type qstate err . (qstate,err) fold_map_config -> qstate -> $t<name> -> (qstate * $t<newName>,err) monad =";
say " fun visitor state x -> _fold_map__$t<name> mk_continue_fold_map visitor state x;;"; say " fun visitor state x -> _fold_map__$t<name> mk_continue_fold_map visitor state x;;";
for $t<ctorsOrFields>.list -> $c for $t<ctorsOrFields>.list -> $c
{ say "let fold_map__$t<name>__$c<name> : type qstate . qstate fold_map_config -> qstate -> { $c<type> || 'unit' } -> (qstate * { $c<newType> || 'unit' }) monad ="; { say "let fold_map__$t<name>__$c<name> : type qstate err . (qstate,err) fold_map_config -> qstate -> { $c<type> || 'unit' } -> (qstate * { $c<newType> || 'unit' },err) monad =";
say " fun visitor state x -> _fold_map__$t<name>__$c<name> mk_continue_fold_map visitor state x;;"; } } say " fun visitor state x -> _fold_map__$t<name>__$c<name> mk_continue_fold_map visitor state x;;"; } }
for $adts.list -> $t for $adts.list -> $t
{ {
say "let no_op_node__$t<name> : type state . state -> $t<name> -> state continue_fold_map -> (state * $t<newName>) monad ="; say "let no_op_node__$t<name> : type state . state -> $t<name> -> (state,_) continue_fold_map -> (state * $t<newName>,_) monad =";
say " fun state v continue ->"; # (*_info*) say " fun state v continue ->"; # (*_info*)
say " match v with"; say " match v with";
if ($t<kind> eq $variant) { if ($t<kind> eq $variant) {
@ -446,7 +446,7 @@ for $adts.list -> $t
} }
for $adts.list -> $t for $adts.list -> $t
{ say "let no_op__$t<name> : type state . state fold_map_config__$t<name> = \{"; { say "let no_op__$t<name> : type state . (state,_) fold_map_config__$t<name> = \{";
say " node__$t<name> = no_op_node__$t<name>;"; say " node__$t<name> = no_op_node__$t<name>;";
say " node__$t<name>__pre_state = (fun state v -> ignore v; return state) ;"; # (*_info*) say " node__$t<name>__pre_state = (fun state v -> ignore v; return state) ;"; # (*_info*)
say " node__$t<name>__post_state = (fun state v new_v -> ignore (v, new_v); return state) ;"; # (*_info*) say " node__$t<name>__post_state = (fun state v new_v -> ignore (v, new_v); return state) ;"; # (*_info*)
@ -460,7 +460,7 @@ for $adts.list -> $t
say ") ;"; } say ") ;"; }
say ' }' } say ' }' }
say "let no_op : type state . state fold_map_config = \{"; say "let no_op : type state . (state,_) fold_map_config = \{";
for $adts.list -> $t for $adts.list -> $t
{ say " $t<name> = no_op__$t<name>;" } { say " $t<name> = no_op__$t<name>;" }
say '};;'; say '};;';

View File

@ -58,8 +58,8 @@ let () =
(* Test that the same fold_map_config can be ascibed with different 'a type arguments *) (* Test that the same fold_map_config can be ascibed with different 'a type arguments *)
let _noi : int fold_map_config = no_op (* (fun _ -> ()) *) let _noi : (int, [> error]) fold_map_config = no_op (* (fun _ -> ()) *)
let _nob : bool fold_map_config = no_op (* (fun _ -> ()) *) let _nob : (bool, [> error]) fold_map_config = no_op (* (fun _ -> ()) *)
let () = let () =
let some_root : root = A [ { a1 = X (A [ { a1 = X (B [ 1 ; 2 ; 3 ]) ; a2 = W () } ]) ; a2 = Z (W ()) } ] in let some_root : root = A [ { a1 = X (A [ { a1 = X (B [ 1 ; 2 ; 3 ]) ; a2 = W () } ]) ; a2 = Z (W ()) } ] in