В любом случае использовать С# неявных операторов из F #?

Если у меня есть класс С# с неявным преобразованием в double, вот так:

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

F # не любит, когда я пытаюсь использовать его, как если бы это был float:

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

Есть ли способ сделать это (я предполагаю, что нет, на основе этого вопроса/ответа), а если нет, то какой достойный обход?

Ответ 1

F # не выполняет неявные преобразования, но позволяет определить явный оператор для их запуска. См. Ответ kvb на предыдущий вопрос:

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

Это использует статически разрешенные параметры типа, чтобы сказать, что либо вход, либо результат должны предоставлять неявный оператор преобразования - они скомпилированы для методы с именем op_Implicit, поэтому компилятор F # проверяет статический метод с этим специальным именем.

Используя оператор !>, вы можете прямо указать, где вы хотите преобразовать Parameter в float (два раза) в примере кода следующим образом:

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

Я думаю, что основная причина не допускать неявных преобразований в F # заключается в том, что это сделает вывод типа немного сложнее, и компилятору будет сложно дать хорошие сообщения об ошибках.

Ответ 3

FSharp.Interop.Dynamic использует DLR, поэтому для большинства людей, вероятно, слишком много, но имеет функцию Dyn.implicitConvert для динамического использования неявного оператора С#.

   [<Test>] member basic.''Test Implicit Conversion'' ()=
                    let ele = 50
                    ele |> Dyn.implicitConvert |> should equal (decimal 50)