diff --git a/src/stages/adt_generator/generator.raku b/src/stages/adt_generator/generator.raku index 85146e887..11d0c5e91 100644 --- a/src/stages/adt_generator/generator.raku +++ b/src/stages/adt_generator/generator.raku @@ -143,7 +143,7 @@ say ""; for $statements -> $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 return v = Simple_utils.Trace.ok v;;"; say "open $moduleName;;"; @@ -151,7 +151,7 @@ say "open $moduleName;;"; say ""; say "(* must be provided by one of the open or include statements: *)"; for $adts.grep({$_ ne $record && $_ ne $variant}).map({$_}).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 ""; for $adts.kv -> $index, $t { @@ -182,34 +182,34 @@ say ";;"; say ""; for $adts.list -> $t { - say "type 'state continue_fold_map__$t = \{"; - say " node__$t : 'state -> $t -> ('state * $t) monad ;"; + say "type ('state, 'err) continue_fold_map__$t = \{"; + say " node__$t : 'state -> $t -> ('state * $t , 'err) monad ;"; for $t.list -> $c - { say " $t__$c : 'state -> {$c || 'unit'} -> ('state * {$c || 'unit'}) monad ;" } + { say " $t__$c : 'state -> {$c || 'unit'} -> ('state * {$c || 'unit'} , 'err) monad ;" } say ' };;'; } -say "type 'state continue_fold_map = \{"; +say "type ('state , 'err) continue_fold_map = \{"; for $adts.list -> $t { - say " $t : 'state continue_fold_map__$t ;"; + say " $t : ('state , 'err) continue_fold_map__$t ;"; } say ' };;'; say ""; for $adts.list -> $t -{ say "type 'state fold_map_config__$t = \{"; - say " node__$t : 'state -> $t -> 'state continue_fold_map -> ('state * $t) monad ;"; # (*Adt_info.node_instance_info ->*) - say " node__$t__pre_state : 'state -> $t -> 'state monad ;"; # (*Adt_info.node_instance_info ->*) - say " node__$t__post_state : 'state -> $t -> $t -> 'state monad ;"; # (*Adt_info.node_instance_info ->*) +{ say "type ('state , 'err) fold_map_config__$t = \{"; + say " node__$t : 'state -> $t -> ('state, 'err) continue_fold_map -> ('state * $t , 'err) monad ;"; # (*Adt_info.node_instance_info ->*) + say " node__$t__pre_state : 'state -> $t -> ('state, 'err) monad ;"; # (*Adt_info.node_instance_info ->*) + say " node__$t__post_state : 'state -> $t -> $t -> ('state, 'err) monad ;"; # (*Adt_info.node_instance_info ->*) for $t.list -> $c - { say " $t__$c : 'state -> {$c || 'unit'} -> 'state continue_fold_map -> ('state * {$c || 'unit'}) monad ;"; # (*Adt_info.ctor_or_field_instance_info ->*) + { say " $t__$c : 'state -> {$c || 'unit'} -> ('state, 'err) continue_fold_map -> ('state * {$c || 'unit'} , 'err) monad ;"; # (*Adt_info.ctor_or_field_instance_info ->*) } say '};;' } -say "type 'state fold_map_config ="; +say "type ('state, 'err) fold_map_config ="; say ' {'; for $adts.list -> $t -{ say " $t : 'state fold_map_config__$t;" } +{ say " $t : ('state, 'err) fold_map_config__$t;" } say ' };;'; say ""; @@ -371,31 +371,31 @@ for $adts.list -> $t say ""; -say "type 'state mk_continue_fold_map = \{"; -say " fn : 'state mk_continue_fold_map -> 'state fold_map_config -> 'state continue_fold_map"; +say "type ('state, 'err) mk_continue_fold_map = \{"; +say " fn : ('state,'err) mk_continue_fold_map -> ('state, 'err) fold_map_config -> ('state , 'err) continue_fold_map"; say '};;'; # fold_map functions say ""; for $adts.list -> $t -{ say "let _fold_map__$t : type qstate . qstate mk_continue_fold_map -> qstate fold_map_config -> qstate -> $t -> (qstate * $t) 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 _fold_map__$t : type qstate err . (qstate,err) mk_continue_fold_map -> (qstate,err) fold_map_config -> qstate -> $t -> (qstate * $t, err) monad = fun mk_continue_fold_map visitor state x ->"; + say " let continue_fold_map : (qstate,err) continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in"; say " visitor.$t.node__$t__pre_state state x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t)*) say " visitor.$t.node__$t state x continue_fold_map >>? fun (state, new_x) ->"; # (*(fun () -> whole_adt_info, info__$t)*) say " visitor.$t.node__$t__post_state state x new_x >>? fun state ->"; # (*(fun () -> whole_adt_info, info__$t)*) say " return (state, new_x);;"; say ""; for $t.list -> $c - { say "let _fold_map__$t__$c : type qstate . qstate mk_continue_fold_map -> qstate fold_map_config -> qstate -> { $c || 'unit' } -> (qstate * { $c || 'unit' }) 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 _fold_map__$t__$c : type qstate err . (qstate,err) mk_continue_fold_map -> (qstate,err) fold_map_config -> qstate -> { $c || 'unit' } -> (qstate * { $c || 'unit' }, err) monad = fun mk_continue_fold_map visitor state x ->"; + say " let continue_fold_map : (qstate,err) continue_fold_map = mk_continue_fold_map.fn mk_continue_fold_map visitor in"; say " visitor.$t.$t__$c state x continue_fold_map;;"; # (*(fun () -> whole_adt_info, info__$t, info__$t__$c)*) say ""; } } # make the "continue" object say ""; 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 ' {'; for $adts.list -> $t { say " $t = \{"; @@ -410,16 +410,16 @@ say ""; # fold_map functions : tying the knot say ""; for $adts.list -> $t -{ say "let fold_map__$t : type qstate . qstate fold_map_config -> qstate -> $t -> (qstate * $t) monad ="; +{ say "let fold_map__$t : type qstate err . (qstate,err) fold_map_config -> qstate -> $t -> (qstate * $t,err) monad ="; say " fun visitor state x -> _fold_map__$t mk_continue_fold_map visitor state x;;"; for $t.list -> $c - { say "let fold_map__$t__$c : type qstate . qstate fold_map_config -> qstate -> { $c || 'unit' } -> (qstate * { $c || 'unit' }) monad ="; + { say "let fold_map__$t__$c : type qstate err . (qstate,err) fold_map_config -> qstate -> { $c || 'unit' } -> (qstate * { $c || 'unit' },err) monad ="; say " fun visitor state x -> _fold_map__$t__$c mk_continue_fold_map visitor state x;;"; } } for $adts.list -> $t { - say "let no_op_node__$t : type state . state -> $t -> state continue_fold_map -> (state * $t) monad ="; + say "let no_op_node__$t : type state . state -> $t -> (state,_) continue_fold_map -> (state * $t,_) monad ="; say " fun state v continue ->"; # (*_info*) say " match v with"; if ($t eq $variant) { @@ -446,7 +446,7 @@ for $adts.list -> $t } for $adts.list -> $t -{ say "let no_op__$t : type state . state fold_map_config__$t = \{"; +{ say "let no_op__$t : type state . (state,_) fold_map_config__$t = \{"; say " node__$t = no_op_node__$t;"; say " node__$t__pre_state = (fun state v -> ignore v; return state) ;"; # (*_info*) say " node__$t__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 "let no_op : type state . state fold_map_config = \{"; +say "let no_op : type state . (state,_) fold_map_config = \{"; for $adts.list -> $t { say " $t = no_op__$t;" } say '};;'; diff --git a/src/test/adt_generator/use_a_fold.ml b/src/test/adt_generator/use_a_fold.ml index 8cfd5aa3a..c065cabf2 100644 --- a/src/test/adt_generator/use_a_fold.ml +++ b/src/test/adt_generator/use_a_fold.ml @@ -58,8 +58,8 @@ let () = (* 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 _nob : bool fold_map_config = no_op (* (fun _ -> ()) *) +let _noi : (int, [> error]) fold_map_config = no_op (* (fun _ -> ()) *) +let _nob : (bool, [> error]) fold_map_config = no_op (* (fun _ -> ()) *) let () = let some_root : root = A [ { a1 = X (A [ { a1 = X (B [ 1 ; 2 ; 3 ]) ; a2 = W () } ]) ; a2 = Z (W ()) } ] in