生成褶皱、iter和地图的类型与ppx_衍生文件不一致



我正在努力正确设置我的OCaml环境,以使用ppx-derives-map、fold和iter,如下所示:https://github.com/ocaml-ppx/ppx_deriving#plugins-iter地图和折叠

我的最小例子是这里(我使用Base,因为这是我在更广泛的项目中使用的库(:

open Base;;
type data = Row of float array | Dim of data array
[@@deriving iter, map, fold, show];;
let t = Row [|2.;2.|];;
pp_data Caml.Format.std_formatter t;;
map_data (fun x -> x +. 1.) t;;
pp_data Caml.Format.std_formatter t;;

以下代码是使用编译的ocamlfind ocamlc -package base -package ppx_deriving.iter -package ppx_deriving.map -package ppx_deriving.fold -package ppx_deriving.show -linkpkg -g test.ml && ./a.out;我收到一个编译错误,指出map_data的类型为data -> data。但根据文档和我的一般知识,map得到了一个函数和一个可映射的结构,而这里似乎不是这样。在utop中测试它会给我同样的错误。

我缺什么了吗?

提前感谢:(

这些Deriver处理多态数据结构,并将用户函数应用于与该结构的类型变量对应的所有值。由于没有任何类型变量,生成的map_data函数是有缺陷的,但很自然,因为没有类型变量意味着一个常量函数。

换句话说,对于一些具有N型变量的多态type ('s1, ..., 'sN) xmap_x函数的一般结构是

('s1 -> 't1) -> ... -> ('sN -> 'tN) -> ('s1,...,'sN) x -> ('t1,...,'tN) x

也就是说,对于每个类型变量,它都期望一个函数将该类型的值映射到其他类型,这样映射函数的参数数就是N+1。在您的情况下,由于没有类型变量,因此没有映射函数,因此只有x -> x

如果你将你的类型重新定义为

type 'a data = Row of 'a array | Dim of 'a data array
[@@deriving iter, map, fold, show]

您将获得预期类型为('a -> 'b) -> 'a data -> 'b datamap_data。deriver甚至会理解数组是一个数据结构,并递归到它中,例如

let input = Dim [|Row [|1;2;3|]; Row [|3;4;5|]|]
map_data (fun x -> x + 1) input;;
- : int data = Dim [|Row [|2; 3; 4|]; Row [|4; 5; 6|]|]

当然,如果你不想在你的界面中使用多态类型,你可以创建一个类型别名,例如

type t = float data

并将map_data公开为

val map_data : (float -> float) -> t -> t

最新更新