Adding Overloaded Constructors to Implicit F# Type

我的未来我决定 提交于 2019-12-11 05:08:41

问题


I have created the following type using implicit type construction:

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"))

However now I need to add the following overloaded constructor to this type (which is in C# here):

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

The problem that I have is that it seems any overloaded constructors in an implicit type must have a parameter list that is a subset of the first constructor. Obviously the constructor I want to add does not meet this requirement. Is there any way to do this using implicit type construction? Which way should I do this? I'm pretty new to F# so if you could show the whole type with your changes in it I would greatly appreciate it.

Thanks in advance,

Bob

P.S. If you have any other suggestions to make my class more in the functional style please feel free to comment on that as well.


回答1:


I would probably just do this:

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 )

unless we are talking about very large arrays which are created very often (i.e. copying the empty array becomes a performance bottleneck).

If you want to emulate the C# version, you need an explicit field that can be accessed from both constructors, like so:

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]

BTW, there is also a matrix type in the F# PowerPack.



来源:https://stackoverflow.com/questions/5212570/adding-overloaded-constructors-to-implicit-f-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!