2011-03-05 161 views
1

我想下面的C#轉換爲F#:在類型使用F#索引屬性

public class Matrix 
    { 
     double[,] matrix; 

public int Cols 
     { 
      get 
      { 
       return this.matrix.GetUpperBound(1) + 1; 
      } 
     } 

public int Rows 
     { 
      get 
      { 
       return this.matrix.GetUpperBound(0) + 1; 
      } 
     } 

     public Matrix(double[,] sourceMatrix) 
     { 
     this.matrix = new double[sourceMatrix.GetUpperBound(0) + 1, sourceMatrix.GetUpperBound(1) + 1]; 
     for (int r = 0; r < this.Rows; r++) 
     { 
      for (int c = 0; c < this.Cols; c++) 
      { 
       this[r, c] = sourceMatrix[r, c]; 
      } 
     } 
     } 

     public double this[int row, int col] 
     { 
     get 
     { 
      return this.matrix[row, col]; 
     } 
     set 
     { 
      this.matrix[row, col] = value; 
     } 
     } 
    } 

這是我到目前爲止有:以上

type Matrix(sourceMatrix:double[,]) = 
let mutable (matrix:double[,]) = Array2D.create (sourceMatrix.GetUpperBound(0) + 1) (sourceMatrix.GetUpperBound(1) + 1) 0.0 
member this.Item 
    with get(x, y) = matrix.[(x, y)] 
    and set(x, y) value = matrix.[(x, y)] <- value 
do 
    for i = 0 to matrix.[i].Length - 1 do 
    for j = (i + 1) to matrix.[j].Length - 1 do 
     this.[i].[j] = matrix.[i].[j] 

我的類型似乎有兩個問題我不知道如何解決。第一個是矩陣。[(x,y)]預計有類型`a []但是類型爲double [,]。第二種是類型定義在成員和接口定義之前必須有let/do綁定。這個問題是我試圖填充do塊中的索引屬性,這意味着我必須先創建它。

由於提前,

鮑勃

回答

6

關於你的第一個問題,你想用matrix.[x,y]而不是matrix.[(x,y)] - 你的矩陣是由兩個整數索引,而不是整數的元組(雖然這些概念類似)。

這裏的東西大致相當於你的C#:

type Matrix(sourceMatrix:double[,]) = 
    let rows = sourceMatrix.GetUpperBound(0) + 1 
    let cols = sourceMatrix.GetUpperBound(1) + 1 
    let matrix = Array2D.zeroCreate<double> rows cols 
    do 
    for i in 0 .. rows - 1 do 
    for j in 0 .. cols - 1 do 
     matrix.[i,j] <- sourceMatrix.[i,j] 
    member this.Rows = rows 
    member this.Cols = cols 
    member this.Item 
    with get(x, y) = matrix.[x, y] 
    and set(x, y) value = matrix.[x, y] <- value 

這是假設你的矩陣實際上不能重新分配(例如,在C#中你張貼,你可以做出你matrixreadonly - 除非還有其他隱藏的代碼)。因此,行和列的數量可以在構造函數中計算一次,因爲矩陣的條目可能會更改,但其大小不會更改。

但是,如果你希望你的代碼更直譯,你可以給你新建成的情況下(在這種情況下this)名稱:

type Matrix(sourceMatrix:double[,]) as this = 
    let mutable matrix = Array2D.zeroCreate<double> (sourceMatrix.GetUpperBound(0) + 1) (sourceMatrix.GetUpperBound(1) + 1) 
    do 
    for i in 0 .. this.Rows - 1 do 
    for j in 0 .. this.Cols - 1 do 
     this.[i,j] <- sourceMatrix.[i,j] 
    member this.Rows = matrix.GetUpperBound(0) + 1 
    member this.Cols = matrix.GetUpperBound(1) + 1 
    member this.Item 
    with get(x, y) = matrix.[x, y] 
    and set(x, y) value = matrix.[x, y] <- value 
+0

對不起,我只是編輯它,粘貼在錯誤的構造函數中。 – Beaker 2011-03-05 21:48:20

+0

優秀的答案,以及只讀的這是你的一個正確的假設。原來的C#不是我的,我忽略了這一點。對C#和F#都很好。 :) – Beaker 2011-03-05 23:35:46

+0

如果有人感興趣,我添加了這個問題的後續問題:http://stackoverflow.com/questions/5212570/adding-overloaded-constructors-to-implicit-f-type – Beaker 2011-03-06 19:07:13

2
type Matrix(sourceMatrix:double[,]) = 
    let matrix = Array2D.copy sourceMatrix 
    member this.Item 
     with get(x, y) = matrix.[x, y] 
     and set(x, y) value = matrix.[x, y] <- value