Reputation: 2946
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?
Upvotes: 2
Views: 155
Reputation: 11525
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
Upvotes: 4
Reputation: 2946
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>
Upvotes: 2