Вопрос

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