Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are F# record types implemented as structs or classes?

Tags:

record

f#

I'm using record types in F# to store some simple data, e.g. as follows:

open Vector

type Point =
    {
        x: float;
        y: float;
        z: float;
    }
    static member (+) (p: Point, v: Vector) = { Point.x = p.x + v.x ; y = p.y + v.y ; z = p.z + v.z }
    static member (-) (p: Point, v: Vector) = { Point.x = p.x - v.x ; y = p.y - v.y ; z = p.z - v.z }
    static member (-) (p1: Point, p2: Point) = { Vector.x = p1.x - p2.x ; y = p1.y - p2.y ; z = p1.z - p2.z }
    member p.ToVector = { Vector.x = p.x ; y = p.y ; z = p.z }

I can't work out whether this will be implemented as a value or reference type.

I've tried putting [<Struct>] before the type definition but this causes all sorts of compile errors.

like image 411
Mark Pattison Avatar asked Jul 07 '11 15:07

Mark Pattison


2 Answers

[<Struct>] is the correct syntax for requesting a value type. It can be seen used in Chapter 6 of 'Expert F#', and this is accepted by F# 2.0:

[<Struct>]
type Point =
  val x: float
  new(x) = {x=x;}

Though if you write it as [<Struct>] type Point = (ie all on one line) it produces a number of warnings (no errors, though). Which version of F# are you using?

like image 64
Jack Lloyd Avatar answered Nov 08 '22 01:11

Jack Lloyd


Records are classes, but all fields are immutable by default. In order to use the "advantage" of reference types, you must set the fields as mutable (you can set some as immutable and some as mutable) and then modify their value:

type Point =
    {
        mutable x : float
        y : float
        z : float
    }
    member p.AddToX Δx = p.x <- p.x + Δx
like image 37
Ramon Snir Avatar answered Nov 07 '22 23:11

Ramon Snir