I'm practicing with F# and I've though of implementing a type-constrained compare function for F#. In C#, it's implemented by this

// in C#
static int cmp<T>(T x, T y) where T: System.IComparable<T>
{
    return x.CompareTo(y);
}

However, in F#, the best way I've come up is this.

(* in F# *)
let cmp (x: 'a when 'a :> 'a System.IComparable) (y: 'a when 'a :> 'a System.IComparable) 
    = x.CompareTo(y)

I tried the one below but it didn't work

let cmp (x: 'a) (y: 'a) when 'a :> 'a System.IComparable
    = x.CompareTo(y)

Is my working F# sample the shortest way or is there another?

有帮助吗?

解决方案

Another (cleaner, IMO) way to implement this is by adding an explicit generic type parameter to the function, like this:

let cmp<'T when 'T :> System.IComparable<'T>> (x : 'T) (y : 'T) =
    x.CompareTo y

其他提示

Ok, found it. I was browsing through the examples in MSDN's F# type constraint and at the thrid from the last example, I found this

let inline add(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) =
    value1 + value2

I notice that constraint for ^T in value1 is used in value2, so I change my cmp function to this

let cmp (x: 'a when 'a :> 'a System.IComparable) (y: 'a) = x.CompareTo(y)

I ran through the fsi and got the same type signature

> let cmp (x: 'a when 'a :> 'a System.IComparable) (y: 'a) = x.CompareTo(y);;

val cmp : 'a -> 'a -> int when 'a :> System.IComparable<'a>

> let cmp (x: 'a when 'a :> 'a System.IComparable) (y: 'a when 'a :> 'a System.IComparable) = x.CompareTo(y);;

val cmp : 'a -> 'a -> int when 'a :> System.IComparable<'a>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top