Reputation: 22133
I have a type defined in C# like this:
struct F {
public static explicit operator F(long value) {}
public static explicit operator long(F value) {}
public static explicit operator F(double value) {}
public static explicit operator double(F value) {}
// more conversion operators
}
In F# if I want to create it from a long, the only way I found is:
let l = F.op_Explicit 3L
I tried creating an inline function to make this nicer:
let inline f a = F.op_Explicit a
But this doesn't compile. I also tried with a member constraint:
let inline f (x:^a) = (F: (static member op_Explicit : ^a -> F) x)
And that doesn't compile either.
Is it possible to define a function or operator to choose the right overload?
On a side note, it does work nicely in the opposite direction:
let f = someF |> int64 // calls the right conversion operator
Upvotes: 7
Views: 500
Reputation: 55184
It's not valid to have a member constraint on a single concrete type; however, this might work for you:
let inline f (x:^a) : F =
let inline g x = ((^b or ^c):(static member op_Explicit : ^b -> ^c) x)
g x
This has the more general type f : ^a -> F when ( ^a or F) : (static member op_Explicit : ^a -> F)
, which is a type that is impossible to manually annotate any value with!
Upvotes: 6