2012-01-16 8 views
2

次のように私は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 

    ... 

そしてIは、例えばlet mat = Matrix.make 5 5 100をコードすることができました。 Matrixモジュールを定義する利点は、そのコンポーネントのタイプを隠すことです。たとえば、私は後で'a list listまたはmapで行列を定義したいかもしれません。私はこのモジュールを変更する必要がありますが、このモジュールを使用するコードは変更しないでください。私は実現

しかし、一つの問題は、私がしなければlet m1 = m0 in ...m1m0が同じ物理アイテムを共有する、ということである:m1への変更はm0に影響を与えます。実際には、これはcopy関数の目的です。しかし、モジュールにいつもをaffectationと呼ぶようにする方法はありますか?

悪いことは、機能let f (m: 'a matrix) = ...のためである、mからf内の任意の変更がmにその値過去の外側のパラメータに影響を与えます。 fを避ける方法はありますか?

答えて

4

let m1 = m0と書くと、m1m0という名前は同じオブジェクトを示します。これは代入ではなく、値と値のバインディングです。 =符号の後の式は単純な名前なので、m1m0の両方の名前はそれらにバインドされています。

変更可能なデータ構造のコピーを作成する場合は、そのコピーを明示的に要求する必要があります。

データを変更せずに渡すことができるようにするには、このデータを変更する必要があります。これは、実際、不変のデータを使用する主な理由です。変更可能なデータを使用する場合は、データ構造と必要に応じてコピーを担当する担当者との間の共有について注意深く考える必要があります。

データ構造を不変に再編成することはできますが、密行列は不変の表現ではかなりのメモリと処理時間が必要なため、不変性が輝く例にはなりません。

5

あなたは簡単に、一緒に何かシャドウコピーを定義することができます:あなたが欲しいときに `copy`を使用し、あなたのコメントを

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 
+0

おかげで...しかし、私は実際にそれを使用する方法を見ていない... – SoftTimur

+2

行列をコピーする。 matri mのフィールド(x、y)のフィールドを変更する場合は、 'write m x y k'を使用します。あなたが 'm(x)。(y)< - k'をしたいとき – Thomas

関連する問題