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.