从 Caml.List 函数转换为基本模块

Convert from Caml.List function to Base module

我是 OCaml 的初学者。

我需要将函数从 Caml 模块转换为 Base 模块。

我以为我可以通过删除 Caml 来做到这一点。但它不工作,因为存在类型错误。

这是我的代码

type 'a t = Node of 'a list * ('a arc list) [@@deriving show] and 'a arc = char * 'a t [@@deriving show]

let rec size (t1 : 'a t)=
  let aux (n : int)(x : 'a arc) = n + size (snd x) in
    match t1 with
    | Node([], [])     -> 0
    | Node(_ :: _, []) -> 1
    | Node([], l)      -> Caml.List.fold_left aux 0 l 
    | Node(_ :: _, l)  -> Caml.List.fold_left aux 1 l ;;

我通过删除 Caml 得到了这个错误。

File "sort.ml", line 47, characters 41-44:
47 |     | Node([], l)      -> List.fold_left aux 0 l 
                                              ^^^
Error: This expression has type int -> 'a arc -> int
       but an expression was expected of type 'b list

有什么建议吗?

Base library provides the List.fold function, which you shall use as a general iterator1. It has a type that differs from the type of List.fold_left from the OCaml standard library and that means it shall be used differently. Namely, it uses labels 将参数传递给函数,参数的顺序也不同(以符合 Janestreet 编码约定)。在您的情况下,要使其工作,您需要在调用此函数时使用标签,例如

let rec size (t1 : 'a t)=
  let aux (n : int)(x : 'a arc) = n + size (snd x) in
  match t1 with
  | Node([], [])     -> 0
  | Node(_ :: _, []) -> 1
  | Node([], l)      -> List.fold ~f:aux ~init:0 l
  | Node(_ :: _, l)  -> List.fold ~f:aux ~init:1 l ;;

1) 您可以使用 List.fold_left 作为 List.fold 的别名,但不推荐这样做,唯一的区别是名称,类型是还是一样