citykid
citykid

Reputation: 11070

How to define a ctor for a struct in F# that in turn calls the struct's default ctor

How do we define a ctor for an immutable struct in F#, that accepts only some of the fields. Or, compared to C# How do we zero out the struct (like by calling this() in the c# example below) in f# ?

c#

struct Point
{
    private readonly int _x;
    private readonly int _y;
    public Point(int x) : this() // Will zero the struct
    {
        _x = x;
    }
    public Point(int y) : this() // Will zero the struct
    {
        _y = y;
    }

}

The Point(x) ctor above zeros out the struct by calling this() and then sets a single field. This is what I am after. The following example is strongly simplified, the question is how to zero the struct and then set just a single field.

f#

type Point =
   struct 
      val X: float
      val Y: float

      new(x: float) = ? // how to zero out the struct and then set ONLY X ?

   end

Upvotes: 3

Views: 1200

Answers (2)

Leaf Garland
Leaf Garland

Reputation: 3687

I think the F# version of your C# code would be something like this

[<Struct>]
type Point =
  val mutable X: float
  val mutable Y: float

let p = Point(X = 1.0)

Although the struct members are mutable, p is not so you cannot set the members again.

// this will cause a compile error
p.X <- 2.0

Upvotes: 4

Tomas Petricek
Tomas Petricek

Reputation: 243051

You can use Point(x, 0.0) to call another constructor in the struct:

type Point =
   struct 
      val X: float
      val Y: float
      new(x: float, y: float) = { X = x; Y = y }
      new(x: float) = Point(x, 0.0)
   end

As a side-note, you can also declare a struct by using an ordinary type definition with the Struct attribute. This is certainly a matter of style, but I tend to prefer this variant:

[<Struct>]
type Point =
  val X: float
  val Y: float
  new(x: float, y: float) = { X = x; Y = y }
  new(x: float) = Point(x, 1.0)

Upvotes: 7

Related Questions