简体   繁体   English

生成的折叠类型、iter 和 map 与 ppx_deriving 文档不一致

[英]Type of generated fold, iter and map not coherent with ppx_deriving documentation

I am struggling to properly set up my OCaml environment to use ppx derivers map, fold and iter, as devined here: https://github.com/ocaml-ppx/ppx_deriving#plugins-iter-map-and-fold我正在努力正确设置我的 OCaml 环境以使用 ppx 派生 map、折叠和迭代,如此处所定义: https://github.com/ocaml-ppx/ppx_deriving#plugins-iter-map-and-fold

My minimal example is here (I am using Base since this is a library I am using in my wider project):我的最小示例在这里(我正在使用 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;;

The following code is compiled with 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 ;下面的代码是用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的; I get a compilation error stating that map_data has type data -> data .我收到一个编译错误,指出map_data的类型为data -> data But according to the documentation and my general knowledge, map gets a function and a mappable structure, which seems not to be the case here.但是根据文档和我的常识, map得到一个 function 和一个可映射的结构,这似乎不是这里的情况。 Testing this in utop gives me the same error.在 utop 中测试这个给了我同样的错误。

Is there anything I am missing?有什么我想念的吗?

Thank you in advance:)先感谢您:)

These derivers work on polymorphic data structures and apply a user function to all values corresponding to the type variables of that structure.这些派生程序处理多态数据结构并将用户 function 应用于与该结构的类型变量对应的所有值。 Since you don't have any type variables the generated map_data function is deficient, but quite natural, as an absence of the type variable implies a constant function.由于您没有任何类型变量,因此生成的map_data function 是有缺陷的,但很自然,因为缺少类型变量意味着常量 function。

In other words, the general structure of the map_x function for some polymorphic type ('s1, ..., 'sN) x with N type variables is换句话说, map_x function 对于一些具有N类型变量的多态type ('s1, ..., 'sN) x的一般结构是

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

Ie, for each type variable it expects a function that maps values of that type to some other type so that the number of arguments to the map function is N+1 In your case since you have zero type variables, there are no mapping functions so you have just x -> x . Ie, for each type variable it expects a function that maps values of that type to some other type so that the number of arguments to the map function is N+1 In your case since you have zero type variables, there are no mapping functions so你只有x -> x

If you will redefine your type as如果您将类型重新定义为

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

You will get map_data with the expect type ('a -> 'b) -> 'a data -> 'b data .您将获得预期类型('a -> 'b) -> 'a data -> 'b data map_data The deriver will even understand that an array is a data structure and recurse into it, eg,派生者甚至会理解数组是一种数据结构并递归到其中,例如,

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|]|]

Of course, if you don't want a polymorphic type in your interface, you can always create a type alias, eg,当然,如果你不想在你的接口中使用多态类型,你总是可以创建一个类型别名,例如,

type t = float data

and expose map_data as并将 map_data 公开为

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM