我正在学习OCaml,目前我正在努力研究如何在OCaml中进行迭代以及如何创建矩阵。我想要一个5 x 5填充0的数组。我知道共享引用存在问题所以我在每次迭代时都创建了一个新数组但是我在其他地方遇到了问题,特别是在第6行。让我知道其他问题,如缩进做法。
open Array;;
let n = ref 5 and i = ref 0 in
let m = Array.make !n 0 in
while !i < !n do
m.(!i) <- Array.make !n 0;;
i := !i + 1;;
done
m;;
答案 0 :(得分:6)
您使用;;
太多了。与流行的看法相反,;;
不是普通OCaml语法的一部分(在我看来无论如何)。这只是告诉顶层(REPL)的一种特殊方式,你希望它能够评估你到目前为止输入的内容。
在;;
之后退出open Array
。但请改为将最后一个;;
更改为;
。
(由于您在代码中按名称引用了Array
模块,恕我直言的风格很好,您也可以完全忽略open Array;;
。)
您想要最后一个;;
,因为您确实希望顶层评估到目前为止您输入的内容。
您的语法错误是由于您的整体代码是这样的
let ... in
let ... in
while ... do
...
done
m
while
是一个表达式(在OCaml中,一切都是表达式),m
是另一个表达式。如果您想要连续使用两个表达式,则它们之间需要;
。因此,;
后需要done
。
您还有类型错误。当您创建m
时,您正在创建一个int数组(您的给定初始值为0)。因此,您无法在代码中稍后将其转换为矩阵(数组数组)。
另外(不要试图让你批评:-)这段代码就像命令式代码一样。这不是特别惯用的OCaml代码。在大多数人的代码中,使用ref
非常罕见。我看到的一个直接改进只是说let n = 5
。您没有在我看到的任何地方更改n
的值(尽管这可能是更大块代码的一部分)。另一项改进是使用for
代替while
。
最后,您可以在一个函数调用中完成整个操作:
let n = 5 in
let m = Array.init n (fun i -> Array.make n 0) in
m
在OCaml中使用显式循环实际上也很少见(至少在我的代码中)。
或者你可以试试这个:
let n = 5 in
let m = Array.make_matrix n n 0 in
m