arrays - 如何总是做一个做作的副本?

标签 arrays module matrix reference ocaml

我定义了一个 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 listmap 定义一个矩阵。我只需要更改此模块,而不是使用此模块的代码。

但我意识到的一个问题是,如果我执行 let m1 = m0 in ...m1m0 将共享一个相同的物理项目:对 m1 的任何更改都会影响 m0。实际上这就是 copy 函数的目的。但是有没有办法让模块一直调用copy来做affectation呢?

更糟糕的是对于函数 let f (m: 'a matrix) = ...fm 中的任何更改将影响将其值传递给 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/

相关文章:

php - 在PHP中将数组中的连续日期分组在一起

go - 导入 go 包时出现问题

matlab - matlab中两个矩阵之间的相关性

c - 出现在数组下标中的 "volatile"关键字的目的是什么?

javascript - 从 mySql 数据库在 php 中返回 JSON

python - 为什么 double 被认为是一个全局名称?

module - 如何向现有的 odoo 模块添加新的菜单项?

android - 在 Android 中的 Canvas 上显示位图图像的一部分

c# - 如何将 3x2 矩阵转换为 4x4 矩阵?

javascript - 无效 'in' 操作数 obj JQUERY - 尝试从 JSON 获取数据时出现类型错误