如何总是制作一个矫揉造作的副本?

Sof*_*mur 2 arrays ocaml module reference matrix

我已经定义了一个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

    ...
Run Code Online (Sandbox Code Playgroud)

然后我可以编码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) = ...,里面的任何变化fm将会影响外参数谁超过其价值m.有没有办法避免f这样做?

Tho*_*mas 5

您可以轻松定义卷影副本,其中包括:

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
Run Code Online (Sandbox Code Playgroud)

  • 如果要复制矩阵,可以使用`copy`.当你想修改matri m的字段(x,y)时,你可以使用`write mxyk`,即.当你想做`m.(x).(y)< - k` (2认同)