OCaml 无法获取数组长度

问题描述 投票:0回答:2

我是 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
2个回答
5
投票

您的代码存在一些问题。

首先,

;;
符号实际上不是 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
中所示。)


0
投票

作为补充建议,我们可以使用

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

© www.soinside.com 2019 - 2024. All rights reserved.