我是 OCaml 新手,现在正在尝试移动数组。 但我在
arr.length
上遇到语法错误。 (第二行)
let shift (arr : array) (k : int) =
let size = arr.length;;
let shifted = Array.make size 0;;
for i = 0 to size- 1 do
if i < k
then shifted.(size- 1 - k + i) <- arr.(i);;
else shifted.(i-k) <- arr.(i);;
done
shifted;;
您的代码存在一些问题。
首先,
;;
符号实际上不是 OCaml 语法的一部分。它仅在解释器(顶层或 REPL)中使用,以告诉解释器何时评估您迄今为止键入的内容。在普通源代码中很少使用它。许多人(包括我)采用一种风格,其中 ;;
是 never 在源文件中使用。
相比之下,几乎每一行都以
;;
结尾,这肯定会导致语法错误。
定义函数局部变量的方式如下:
let var = expr in
(* rest of function comes here *)
所以你应该有
let size = Array.length arr in
let shifted = Array.make size 0 in
. . .
您应该删除所有
;;
令牌并根据需要添加 in
。
此外,您正在使用一种面向对象的语法。但数组不是 OO 风格的对象。获取名为 arr 的数组的长度:
Array.length arr
它的外观如下:
# let arr = Array.make 10 0;;
val arr : int array = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]
# Array.length arr;;
- : int = 10
# Array.length [| "another"; "example" |];;
- : int = 2
换句话说,
length
是Array
模块中定义的函数。 OCaml 数组不是(OO 类型的)对象,并且没有方法。
(为了将来参考,OCaml 对象的方法是使用
#
引用的,如 object#method
中所示。)
Array.init
和异常处理来轻松实现这一点,方法是通过返回 Invalid_argument
来处理越界访问抛出的 0
异常。
# let shift arr k =
Array.init
(Array.length arr)
(fun i -> try arr.(i + k) with Invalid_argument _ -> 0)
val shift : int array -> int -> int array = <fun>
# shift [|1; 2; 3; 4|] 1;;
- : int array = [|2; 3; 4; 0|]
# shift [|1; 2; 3; 4|] 2;;
- : int array = [|3; 4; 0; 0|]
进一步细化可能会提供默认值,以便
shift
的类型可以泛化为 'a array -> int -> 'a -> 'a array
。