Skip to content

Commit ba1ea6f

Browse files
authored
Merge pull request #12 from yallop/arity
Convert generated nested functions into multi-argument functions
2 parents 43df563 + 0d49293 commit ba1ea6f

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

lib/genletrec.ml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,23 @@ struct
1313
open Asttypes
1414
open Parsetree
1515

16+
(* Convert nested functions fun x -> fun y -> e
17+
into multi-argument functions fun x y -> e *)
18+
let rec squish_arity : expression -> expression = function
19+
| { pexp_desc =
20+
Pexp_function (ps, None,
21+
Pfunction_body ({pexp_desc =
22+
Pexp_function (ps', None, b)} as d')) } as d ->
23+
squish_arity { d with pexp_desc = Pexp_function (ps @ ps', None, b);
24+
pexp_attributes = d.pexp_attributes @ d'.pexp_attributes }
25+
| e -> e
26+
1627
let letrec : (string * expression) list -> expression -> expression =
1728
fun bindings e ->
1829
let binding (x, e) =
1930
{ pvb_pat = Ast_helper.Pat.var (Location.mknoloc x);
2031
pvb_constraint = None;
21-
pvb_expr = e;
32+
pvb_expr = squish_arity e;
2233
pvb_attributes = [];
2334
pvb_loc = Location.none } in
2435
match bindings with

lib_test/arity.ml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
(*
2+
* Copyright (c) 2025 Jeremy Yallop.
3+
*
4+
* This file is distributed under the terms of the MIT License.
5+
* See the file LICENSE for details.
6+
*)
7+
8+
open Letrec
9+
10+
module Sym = struct
11+
type _ t =
12+
Z : int t
13+
| S : 'a t -> (int -> 'a) t
14+
let rec eql : type a b. a t -> b t -> (a, b) eql option =
15+
fun x y ->
16+
match x, y with
17+
| Z , Z -> Some Refl
18+
| S x, S y -> begin match eql x y with
19+
| Some Refl -> Some Refl
20+
| None -> None
21+
end
22+
| _ -> None
23+
end
24+
25+
module R = Letrec.Make(Sym)
26+
27+
let rec mkrhs : type a. (int code list -> int code) -> a Sym.t -> a code =
28+
fun k -> function
29+
| Z -> k []
30+
| S n -> .< fun x -> .~(mkrhs (fun l -> k (.<x>. :: l)) n)>.
31+
32+
let sumn n =
33+
let rhs _ = mkrhs (List.fold_left (fun x y -> .< .~x + .~y >.) .<0>.) in
34+
R.letrec {R.rhs} (fun {R.resolve} -> resolve n)

lib_test/tests.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@ let () = begin
3131

3232
pr "(* Custom equality for indexes *)@\n";
3333
pr "%a@." print_code Custom_eq.evenp_oddp;
34+
35+
pr "(* Generating functions of varying arity *)@\n";
36+
pr "%a@." print_code Arity.(sumn Sym.(S (S (S Z))));
3437
end

0 commit comments

Comments
 (0)