Search code examples
c#f#implicit-conversion

Is there anyway to use C# implicit operators from F#?


If I have a C# class with implicit conversion to double, like so:

public class Parameter
{
    private double _value;
    public Parameter(double value) { _value = value }
    public static implicit operator double(Parameter p) { return _value; }
}

F# doesn't like me trying to use it as if it were a float:

let a = Parameter(4.0)
let b = Parameter(2.0)
let c = a * Math.Sin(b) <-- 'expected float, here Parameter'

Is there any way to do this (I'm guessing there isn't, based on this question/answer), and if not, what would be a decent workaround?


Solution

  • F# does not perform implicit conversions, but it allows you to define an explicit operator to run them. See the kvb's answer to a previous question:

    let inline (!>) (x:^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x) 
    

    This is using statically resolved type parameters to say that either the input or the result needs to provide implicit conversion operator - these are compiled to methods named op_Implicit, so the F# compiler checks for a static method with this special name.

    Using the !> operator, you can now explicitly say where you want to convert Parameter to a float (two times) in your code sample like this:

    let a = Parameter(4.0) 
    let b = Parameter(2.0) 
    let c = !> a * Math.Sin(!> b)
    

    I think the main reason for not allowing implicit conversions in F# is that it would make the type inference a bit more difficult and it would be hard for the compiler to give good error messages.