简体   繁体   中英

Creating an F# record type with a constant value

Let's say I have a record defined thusly...

type Employee = {Name : string; Salary : int}

and I want another type where Salary is fixed. I'd like to be able to say...

type Manager = {Name: string; Salary : int = 250000}

...but it seems I can't.

What options do I have to get this behaviour?

You can give your record a read-only property :

type Manager = 
    {
        Name: string
    }
     member this.Salary = 250000

FSI example:

> let m = { Name = "Foo" };;

val m : Manager = {Name = "Foo";}

> m.Name;;
val it : string = "Foo"
> m.Salary;;
val it : int = 250000

F# records are immutable, so all field values are "fixed", in your terms.

If your goal is to avoid specifying Salary upon construction, the simplest way is to make a "constructor":

type Manager = {Name : string; Salary : int} with
    static member Make name =
        {Manager.Name=name; Salary=250000}

Note 1. I used Manager.Name so that it did not interfere with Employee construction;
Note 2. Also, this approach does not even prevent from keeping a single type Employee that will also gracefully handle Manager's creation; just call the method eg MakeManager for clarity.

A static method does not prohibit someone (a developer who uses your library) from manually creating a Manager with wrong salary. See this answer for how to prevent such creation.

Record type could have members, eg

  type Employee = {Name : string; Salary : int}
  type Manager =
    {Name: string; }
    member x.Salary with get() = 250000
  let manager1 = {Manager.Name = "manager1"}
  let manager2 = { manager1 with Manager.Name = "manager2"}
  let salary = manager1.Salary // fsi: val salary : int = 250000

But here if a manager is an employee, I would use normal classes and inheritance instead of records. It is perfectly fine to use normal classes from F# and immutability could be achieved by avoiding public setters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM