В любом случае использовать С# неявных операторов из 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 # заключается в том, что это сделает вывод типа немного сложнее, и компилятору будет сложно дать хорошие сообщения об ошибках.
Ответ 2
Это не позволит вам делать неявные преобразования. Сделайте свои преобразования явным, где вам нужно.
Смотрите здесь различные способы сделать это явно:
http://natehoellein.blogspot.com/2008/02/basic-type-conversions-with-f.html
Ответ 3
FSharp.Interop.Dynamic использует DLR, поэтому для большинства людей, вероятно, слишком много, но имеет функцию Dyn.implicitConvert
для динамического использования неявного оператора С#.
[<Test>] member basic.''Test Implicit Conversion'' ()=
let ele = 50
ele |> Dyn.implicitConvert |> should equal (decimal 50)