Interface
Syntax
Similar to an abstract class but with only abstract members.
Atttribute:
[<AbstractClass>]
attribute can not be used to declare an interface[<Interface>]
attribute is optional but recommended in most cases
type [accessibility-modifier] interface-name =
abstract memberN : [ argument-typesN -> ] return-typeN
Interface name begins with
I
to follow .NET conventionArguments can be named (without parentheses otherwise 💥)
[<Interface>]
type IPrintable =
abstract member Print : format: string -> unit
You can also use verbose syntax with an interface ... end
block.
→ Not idiomatic except in the case of a member-less interface a.k.a marker interface.
type IMarker = interface end
Implementation
2 ways of implementing an interface:
In an object expression 📍
In a type (as in C♯)
type IPrintable =
abstract member Print : unit -> unit
type Range = { Min: int; Max: int } with
interface IPrintable with
member this.Print() = printfn $"[{this.Min}..{this.Max}]"
Default implementation
F♯ 5.0 supports interfaces defining methods with default implementations written in C♯ 8+ but does not allow them to be defined directly in F♯.
F♯ interface is explicit
F♯ interface implementation ≡ Explicit implementation of an interface in C♯
→ Interface methods are accessible only by upcasting:
[<Interface>]
type IPrintable =
abstract member Print : unit -> unit
type Range = { Min: int; Max: int } with
interface IPrintable with
member this.Print() = printfn $"[{this.Min}..{this.Max}]"
let range = { Min = 1; Max = 5 }
(range :> IPrintable).Print() // upcast operator
// [1..5]
Implementing a generic interface
[<Interface>]
type IValue<'T> =
abstract member Get : unit -> 'T
// Contrived example for demo purpose
type DoubleValue(i, s) =
interface IValue<int> with
member _.Get() = i
interface IValue<string> with
member _.Get() = s
let o = DoubleValue(1, "hello")
let i = (o :> IValue<int>).Get() // 1
let s = (o :> IValue<string>).Get() // "hello"
Inheritance
Defined with inherit
keyword
type A(x: int) =
do
printf "Base (A): "
for i in 1..x do printf "%d " i
printfn ""
type B(y: int) =
inherit Base(y * 2) // 👈
do
printf "Child (B): "
for i in 1..y do printf "%d " i
printfn ""
let child = B(1)
// Base: 1 2
// Child: 1
// val child: B
Last updated
Was this helpful?