我定义了一个 Matrix
模块如下:
module Matrix =
struct
type 'a matrix = 'a array array
let make (nr: int) (nc: int) (init: 'a) : 'a matrix =
let result = Array.make nr (Array.make nc init) in
for i = 0 to nr - 1 do
result.(i) <- Array.make nc init
done;
result
let copy (m: 'a matrix) : 'a matrix =
let l = nbrows m in
if l = 0 then m else
let result = Array.make l m.(0) in
for i = 0 to l - 1 do
result.(i) <- Array.copy m.(i)
done;
result
...
然后我可以编写代码,例如 let mat = Matrix.make 5 5 100
。定义Matrix
模块的好处是隐藏其组件的类型。例如,我稍后可能想用 'a list list
或 map
定义一个矩阵。我只需要更改此模块,而不是使用此模块的代码。
但我意识到的一个问题是,如果我执行 let m1 = m0 in ...
,m1
和 m0
将共享一个相同的物理项目:对 m1
的任何更改都会影响 m0
。实际上这就是 copy
函数的目的。但是有没有办法让模块一直调用copy
来做affectation
呢?
更糟糕的是对于函数 let f (m: 'a matrix) = ...
,f
到 m
中的任何更改将影响将其值传递给 m
的外部参数。有没有办法避免 f
这样做?
最佳答案
您可以轻松定义卷影副本,以及一些东西:
type 'a m =
| Shared of 'a matrix
| Matrix of 'a array array
and 'a matrix = {
mutable m : 'a m;
}
let copy_matrix m = [... YOUR CODE FOR COPY ...]
(* Shadow copy *)
let copy matrix =
{ m = Shared matrix }
let rec content m =
match m.m with
| Shared m -> content m
| Matrix m -> m
let write m x y k =
let c = match m.m with
| Shared matrix ->
(* Break the shared chain & copy the initial shared matrix *)
let c = copy_matrix (content matrix) in
m.m <- Matrix c;
c
| Matrix m -> m in
c.(x).(y) <- k
关于arrays - 如何总是做一个做作的副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8887373/