Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting F# Record

Tags:

f#

My understanding is that F# records are non-sealed classes. if so, can I inherit a record type? For example:

type person = {name:string; address:string}
type employee inherit person = {employeeId: string}

I have searching around the MSDN docs and language specs and I am not having any luck. Thanks in advance

like image 584
Jamie Dixon Avatar asked Dec 02 '14 14:12

Jamie Dixon


People also ask

What are the 4 different types of inheritance relationship?

There are different types of inheritance viz., Single inheritance, Multiple inheritance, Multilevel inheritance, hybrid inheritance, and hierarchical inheritance. Single Inheritance: When a derived class inherits only from one base class, it is known as single inheritance.

What are the two types of inherit?

Because we clearly observe that there is two kinds of inheritance here- Hierarchical and Single Inheritance.

What is meant by inheriting a class?

Inheritance is the procedure in which one class inherits the attributes and methods of another class. The class whose properties and methods are inherited is known as the Parent class. And the class that inherits the properties from the parent class is the Child class.


2 Answers

F# records cannot be inherited - as Matthew mentions, they are compiled to sealed classes, but it is also an aspect of the F# types system which simply does not allow this.

In practice, you could go with an ordinary class declaration. This means that you won't be able to use the { person with ... } syntax and you won't get the automatic structural equality, but it might make sense if you want to create C#-friendly code:

type Person(name:string) =
  member x.Name = name

type Employee(name:string, id:int) = 
  inherit Person(name)
  member x.ID = id

I think the preferred option would be to use composition rather than inheritance and make employee a record that is composed of some personal information and ID:

type PersonalInformation = { Name : string }

type Employee = 
  { Person : PersonalInformation 
    ID : int }

I probably would not make a person a part of employee (that does not feel right to me, but that is just an intuition), which is why I renamed it to PersonalInformation here.

I suppose another option would be to have IPerson as an interface and have a record Employee implementing the interface:

type IPerson = 
  abstract Name : string

type Employee = 
  { ID : int
    Name : string }
  interface IPerson with
    member x.Name = x.Name

Which one is the best really depends on the concrete thing that you're modelling. But I think interfaces and composition are generally preferred in F# :-)

like image 197
Tomas Petricek Avatar answered Nov 16 '22 04:11

Tomas Petricek


They are sealed classes, here's the first few lines of the class that's generated for person:

[CompilationMapping(SourceConstructFlags.RecordType)]
[Serializable]
public sealed class person 
: IEquatable<person>, 
  IStructuralEquatable, 
  IComparable<person>, 
  IComparable, 
  IStructuralComparable
like image 29
Matthew Mcveigh Avatar answered Nov 16 '22 02:11

Matthew Mcveigh