// Automatic generalization
let swap (a, b) = (b, a) // 'a * 'b -> 'b * 'a
// Explicit generic types and constraints
type Stack<'T>() =
let items = ResizeArray<'T>()
member _.Push(x: 'T) = items.Add x
member _.Pop() =
let x = items[items.Count - 1]
items.RemoveAt(items.Count - 1)
x
member _.Count = items.Count
let maxOf<'T when 'T: comparison> (xs: 'T list) = List.max xs
let printAll<'T when 'T :> System.IFormattable> (xs: 'T list) = xs |> List.iter (fun x -> printfn "%s" (x.ToString("G", null)))
let create<'T when 'T: (new: unit -> 'T)> () = new 'T()
// Other constraints: 'T: equality, 'T: struct, 'T: not struct, 'T: null, 'T: unmanaged, 'T: enum<int>, 'T: delegate<...>
// inline functions and statically resolved type parameters (SRTP)
let inline add x y = x + y // works for int, float, decimal, string, ...
add 1 2, add 1.5 2.5, add "a" "b"
let inline double x = x + x
let inline sumOf (xs: ^T list) = List.fold (+) LanguagePrimitives.GenericZero xs
sumOf [1; 2; 3], sumOf [1.0; 2.0]
// Member constraints: anything with a .Length property
let inline length (x: ^T) = (^T: (member Lengt
…