66 * Learn-OCaml is distributed under the terms of the MIT license. See the
77 * included LICENSE file for details. *)
88
9- (* * Library of heterogeneous, nonempty lists and their corresponding types .
9+ (* * [Fun_ty] is used by [Test_lib] to implement n-ary graders .
1010
11- let p = [%funty: int -> bool]
11+ This module provides two GADTs: [args], representing arguments of
12+ n-ary functions as nonempty heterogeneous lists, and [fun_ty],
13+ representing function types in a more explicit way than ['a Ty.ty].
1214
13- val p : ((int -> bool) Ty.ty, int -> unit, bool) Fun_ty.fun_ty = <abstr>
14- *)
15+ This module also serves as a runtime library for the customized
16+ [ppx_metaquot] distributed with learn-ocaml, so that one may write:
1517
16- (* * The type of arguments, represented as heterogeneous lists.
18+ [let p = [%funty: int -> bool]], and get:
19+
20+ [val p : ((int -> bool) Ty.ty, int -> unit, bool) fun_ty = <abstr>] *)
21+
22+ (* * GADT for arguments of n-ary functions, implemented as nonempty
23+ heterogeneous lists.
1724
1825 Usage: [arg 3 @@ arg "word" @@ last false]
1926
20- Alternatively: [3 @: "word" @:!! false]
21- *)
27+ Alternatively: [3 @: "word" @:!! false] *)
2228type ('arrow, 'uarrow, 'ret) args
29+
30+ (* * [last e], or equivalently [!! e], builds a one-element argument list *)
2331val last :
2432 'a ->
2533 ('a -> 'ret , 'a -> unit , 'ret ) args
34+
35+ (* * [arg e l], or equivalently [e @: l], adds [e] in front of the
36+ argument list [l] *)
2637val arg :
2738 'a ->
2839 ('ar -> 'row , 'ar -> 'urow , 'ret ) args ->
2940 ('a -> 'ar -> 'row , 'a -> 'ar -> 'urow , 'ret ) args
3041
31- val apply : ('ar -> 'row ) -> ('ar -> 'row , 'ar -> 'urow , 'ret ) args -> 'ret
42+ (* * [apply f l] applies a n-ary function [f] to the arguments from [l] *)
43+ val apply :
44+ ('ar -> 'row ) -> ('ar -> 'row , 'ar -> 'urow , 'ret ) args ->
45+ 'ret
46+
47+ (* * GADT for function types.
48+
49+ Given an arrow type ['a -> 'row], the following construct provides
50+ a more precise representation of this function type than
51+ [[%ty: 'a -> 'row] : ('a -> 'row) Ty.ty]:
52+
53+ [[%funty: 'a -> 'row] : (('a -> 'row) Ty.ty, 'a -> 'urow, 'ret) fun_ty]
54+
55+ In particular, the codomain type ['ret] is made explicit, so that
56+ if ['row = 'b -> 'c], we get ['urow = 'b -> unit] and ['ret = 'c].
3257
33- (* * The type of function prototypes.
58+ Usage: [arg_ty [%ty: int] @@ arg_ty [%ty: string] @@
59+ last_ty [%ty: bool] [%ty: unit]]
3460
35- Usage:
36- [arg_ty [%ty: int]
37- @@ arg_ty [%ty: string] @@ last_ty [%ty: bool] [%ty: unit]]
38- *)
61+ Alternatively: [[%funty: int -> string -> bool -> unit]] *)
3962type ('arrow, 'uarrow, 'ret) fun_ty
63+
64+ (* * [last_ty [%ty: a] [%ty: r]] builds a function type for [a -> r] *)
4065val last_ty :
4166 'a Ty .ty ->
4267 'ret Ty .ty ->
4368 (('a -> 'ret ) Ty .ty , 'a -> unit , 'ret ) fun_ty
69+
70+ (* * [arg_ty [%ty: a] [%funty: b ->...-> r]] builds a function type for
71+ [a -> b ->...-> r] *)
4472val arg_ty :
4573 'a Ty .ty ->
4674 (('ar -> 'row ) Ty .ty , 'ar -> 'urow , 'ret ) fun_ty ->
4775 (('a -> 'ar -> 'row ) Ty .ty , ('a -> 'ar -> 'urow ), 'ret ) fun_ty
4876
77+ (* * [ty_of_fun_ty funty] returns a term of type [('ar -> 'row) Ty.ty],
78+ assuming [funty : (('ar -> 'row) Ty.ty, _, _) fun_ty] *)
4979val ty_of_fun_ty :
50- (('ar -> 'row ) Ty .ty , 'ar -> 'urow , 'ret ) fun_ty -> ('ar -> 'row ) Ty .ty
80+ (('ar -> 'row ) Ty .ty , 'ar -> 'urow , 'ret ) fun_ty ->
81+ ('ar -> 'row ) Ty .ty
82+
83+ (* * [get_ret_ty funty] returns a term of type ['ret Ty.ty], assuming
84+ [funty : (_ , _, 'ret) fun_ty] *)
5185val get_ret_ty :
5286 ('p -> 'a ) Ty .ty -> ('p -> 'a , 'p -> 'c , 'ret ) args -> 'ret Ty .ty
5387
88+
89+ (* * Signature [S] is intended to be instantiated in [Test_lib] with:
90+ [module M = struct
91+ let typed_printer ty ppf v = Introspection.print_value ppf v ty
92+ let typed_sampler = Introspection.get_sampler
93+ end] *)
5494module type S = sig
55- val typed_printer : 'a Ty .ty -> Format .formatter -> 'a -> unit
56- val typed_sampler : 'a Ty .ty -> unit -> 'a
95+ val typed_printer :
96+ 'a Ty .ty -> Format .formatter -> 'a -> unit
97+ val typed_sampler :
98+ 'a Ty .ty -> unit -> 'a
5799end
58100
101+ (* * [Make(M)] provides a generic printer and sampler for the arguments
102+ of n-ary functions specified using [args] and [fun_ty] GADTs *)
59103module Make : functor (M : S ) -> sig
60104 val print :
61105 (('p -> 'a ) Ty .ty , 'p -> 'c , 'r ) fun_ty ->
@@ -65,13 +109,19 @@ module Make : functor (M : S) -> sig
65109 unit -> ('p -> 'a , 'p -> 'c , 'r ) args
66110end
67111
112+ (* * [apply_args_1], [apply_args_2], [apply_args3], [apply_args_4] are
113+ variants of the [apply] function, assuming a fixed number of args;
114+ they have thus a more precise type and are used in [Test_lib] *)
68115val apply_args_1 :
69116 ('a -> 'b ) -> ('a -> 'c , 'a -> unit , 'c ) args -> 'b
117+
70118val apply_args_2 :
71119 ('a -> 'b -> 'c ) -> ('a -> 'b -> 'd , 'a -> 'b -> unit , 'd ) args -> 'c
120+
72121val apply_args_3 :
73122 ('a -> 'b -> 'c -> 'd ) ->
74123 ('a -> 'b -> 'c -> 'e , 'a -> 'b -> 'c -> unit , 'e ) args -> 'd
124+
75125val apply_args_4 :
76126 ('a -> 'b -> 'c -> 'd -> 'e ) ->
77127 ('a -> 'b -> 'c -> 'd -> 'f , 'a -> 'b -> 'c -> 'd -> unit , 'f ) args -> 'e
0 commit comments