如何在 OCaml 中实现 Array.to_list 和 Array.of_list

How to implement Array.to_list and Array.of_list in OCaml

我想知道 Array 模块的 to_list 和 of_list 函数的实现。

OCamlStdlib代码可读性很强,大家可以在stdlib/array.ml.

中自行查看

这里是,供参考:

let rec list_length accu = function
  | [] -> accu
  | _::t -> list_length (succ accu) t

let to_list a =
  let rec tolist i res =
     if i < 0 then res
     else tolist (i - 1) (unsafe_get a i :: res)
  in
  tolist (length a - 1) []

let of_list = function
    [] -> [||]
  | hd::tl as l ->
      let a = create (list_length 0 l) hd in
      let rec fill i = function
          [] -> a
        | hd::tl -> unsafe_set a i hd; fill (i+1) tl
      in
      fill 1 tl

备注:

unsafe_getunsafe_setlengthcreate 是在外部定义的(不在 OCaml 中)。

Array模块有自己的List.length版本来避免循环依赖。

如果您想知道这些函数在标准库中是如何实现的,欢迎您阅读实现的source code,因为它是最好的参考。

如果您想知道如何使用标准库函数实现这些函数(即不依赖内部表示,只有标准库的实现者知道),那么这里是这些函数的可能实现,

let array_to_list xs =
  Array.fold_right List.cons xs []

let array_of_list xs = match xs with
  | [] -> [||]
  | default :: _ ->
    let arr = Array.make (List.length xs) default in
    List.iteri (Array.set arr) xs;
    arr