Добавление перегруженных конструкторов в неявный тип F # - PullRequest
1 голос
/ 06 марта 2011

Я создал следующий тип, используя неявную конструкцию типа:

open System

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]

  //Properties

  ///The number of Rows in this Matrix.
  member this.Rows = rows

  ///The number of Columns in this Matrix.
  member this.Cols = cols

  ///Indexed Property for this matrix.
  member this.Item
    with get(x, y) = matrix.[x, y]
     and set(x, y) value = 
        this.Validate(x,y)
        matrix.[x, y] <- value

  //Methods
  /// Validate that the specified row and column are inside of the range of the matrix.
  member this.Validate(row, col) =
    if(row >= this.Rows || row < 0) then raise (new ArgumentOutOfRangeException("row is out of range"))
    if(col >= this.Cols || col < 0) then raise (new ArgumentOutOfRangeException("column is out of range"))

Однако теперь мне нужно добавить следующий перегруженный конструктор к этому типу (который находится здесь в C #):

public Matrix(int rows, int cols)
    {
        this.matrix = new double[rows, cols];
    }

Проблема, с которой я столкнулся, заключается в том, что, похоже, любые перегруженные конструкторы неявного типа должны иметь список параметров, который является подмножеством первого конструктора.Очевидно, что конструктор, который я хочу добавить, не соответствует этому требованию.Есть ли способ сделать это, используя неявную конструкцию типа?Каким образом я должен это сделать?Я довольно новичок в F #, поэтому, если бы вы могли показать весь тип со своими изменениями, я был бы очень признателен.

Заранее спасибо,

Боб

PSЕсли у вас есть другие предложения, чтобы сделать мой класс более функциональным, пожалуйста, не стесняйтесь комментировать это.

1 Ответ

3 голосов
/ 06 марта 2011

Я бы, наверное, просто сделал это:

type Matrix(sourceMatrix:double[,]) =
  let matrix = Array2D.copy sourceMatrix
  let rows = (matrix.GetUpperBound 0) + 1
  let cols = (matrix.GetUpperBound 1) + 1

  new(rows, cols) = Matrix( Array2D.zeroCreate rows cols )

, если мы не говорим об очень больших массивах, которые создаются очень часто (то есть копирование пустого массива становится узким местом производительности).

Если вы хотите эмулировать версию C #, вам нужно явное поле, к которому можно получить доступ из обоих конструкторов, например:

type Matrix(rows,cols) as this =

  [<DefaultValue>]
  val mutable matrix : double[,]
  do this.matrix <- Array2D.zeroCreate rows cols

  new(source:double[,]) as this =
    let rows = source.GetUpperBound(0) + 1
    let cols = source.GetUpperBound(1) + 1
    Matrix(rows, cols)
    then
      for i in 0 .. rows - 1 do
        for j in 0 .. cols - 1 do
          this.matrix.[i,j] <- source.[i,j]

Кстати, в F # PowerPack также есть матричный тип .

...