如何在 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_get
、unsafe_set
、length
和 create
是在外部定义的(不在 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
我想知道 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_get
、unsafe_set
、length
和 create
是在外部定义的(不在 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