Statically Resolved Type Parameters
Syntax#
s
is an instance of^a
you want to accept at compile-time, which can be anything that implements the members you actually call using the syntax.^a
is similar to generics which would be'a
(or'A
or'T
for example) but these are compile-time resolved, and allow for anything that fits all the requested usages within the method. (no interfaces required)
Simple usage for anything that has a Length member
let inline getLength s = (^a: (member Length: _) s)
//usage:
getLength "Hello World" // or "Hello World" |> getLength
// returns 11
Class, Interface, Record usage
// Record
type Ribbon = {Length:int}
// Class
type Line(len:int) =
member x.Length = len
type IHaveALength =
abstract Length:int
let inline getLength s = (^a: (member Length: _) s)
let ribbon = {Length=1}
let line = Line(3)
let someLengthImplementer =
{ new IHaveALength with
member __.Length = 5}
printfn "Our ribbon length is %i" (getLength ribbon)
printfn "Our Line length is %i" (getLength line)
printfn "Our Object expression length is %i" (getLength someLengthImplementer)
Static member call
this will accept any type with a method named GetLength
that takes nothing and returns an int:
((^a : (static member GetLength : int) ()))