The Announcing F #7 page gives the example code
type IAddition<'T when 'T :> IAddition<'T>> =
static abstract op_Addition: 'T * 'T -> 'T
type Number<'T when IAddition<'T>>(value: 'T) =
member _.Value with get() = value
interface IAddition<Number<'T>> with
static member op_Addition(a, b) = Number(a.Value + b.Value)
How do you instantiate a value of type Number? It would seem you have to pass a generic argument of some type MyType that implements IAddition<MyType>. But then from the IAddition definition, MyType also has to implement IAddition<MyType>, and so on. So how do you get off the ground?
Also, what is the difference between 'T when 'T :> IAddition<'T> and 'T when IAddition<'T>? I can't find documentation on this.
The Number class in this example is a bit pointless, since it does nothing but reimplement addition, but here's an example that shows how it can be instantiated:
type MyType = MyInt of int with
interface IAddition<MyType> with
static member (+)(MyInt a, MyInt b) =
MyInt (a + b)
let x = Number(MyInt 1)
Note that MyType implements IAddition<MyType>, which means it can be wrapped via Number. As Fyodor mentioned, there is no infinite regress.
As far as I know, there is no difference between 'T when 'T :> IAddition<'T> and 'T when IAddition<'T>, but I could be wrong. The second form is not well documented, I think.