我想了解Array.length是如何实现的。我设法用Array.fold_left
:写了它
let length a = Array.fold_left (fun x _ -> x + 1) 0 a
然而,在标准库中,fold_left
使用length
,所以这不可能。对于length
,stdlib中只有这一行我不理解:
external length : 'a array -> int = "%array_length"
如何在不使用fold_left
的情况下编写length
?
编辑:
我试着用模式匹配来做,但它并不是详尽无遗的,我如何才能使匹配更精确?(目的是删除最后一个元素,当只剩下一个元素时返回i+1(
let length a =
let rec aux arr i =
match arr with
| [|h|] -> i+1
| [|h;t|] -> aux [|h|] (i+1)
in aux a 0;;
数组类型是一个基元类型,类似于int
类型。许多基元函数在这些基元类型上的实现是用C函数或编译器基元完成的。
Array.length
函数属于编译器基元类别,在标准库中由定义
external length : 'a array -> int = "%array_length"
这里,该声明将值length
绑定到类型为'a array -> int
的编译器原语%array_length
(编译器原语名称以%
符号开头(。在从源代码到本机代码或字节码的转换过程中,编译器将这种编译器原语转换为较低级别的实现。
换句话说,您自己无法以有效的方式重新实现Array.length
或数组类型,因为该类型是编译器本身定义的基本构建块。
对于
length
,stdlib中只有一行我不理解:
external
关键字表示此函数是用C实现的,"%array_length"
是命名此函数的C符号。OCaml运行时是用C语言实现的,一些类型(如数组(是内置的(也称为基元(。
参见第20章:用OCaml接口C中的实现原语示例
我试着用模式匹配来做这件事,但它并不是详尽无遗的,我如何才能使匹配更精确
请注意,OCaml告诉您哪种模式不匹配:
Here is an example of a case that is not matched:
[| |]
所以你也必须考虑空向量。