17

如果我有一个隐式转换为 double 的 C# 类,如下所示:

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'

有没有办法做到这一点(我猜没有,基于这个问题/答案),如果没有,什么是体面的解决方法?

4

3 回答 3

31

F# 不执行隐式转换,但它允许您定义显式运算符来运行它们。请参阅kvb 对上一个问题的回答

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

这是使用静态解析的类型参数来表示输入或结果需要提供隐式转换运算符 - 这些被编译为名为 的方法op_Implicit,因此 F# 编译器检查具有此特殊名称的静态方法。

使用!>运算符,您现在可以在代码示例中明确说明要转换Parameterfloat(两次)的位置,如下所示:

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

我认为在 F# 中不允许隐式转换的主要原因是它会使类型推断更加困难,并且编译器很难给出好的错误消息。

于 2012-05-23T12:37:54.840 回答
1

它不会让您进行隐式转换。在需要的地方明确转换。

有关明确执行此操作的各种方法,请参见此处:http: //natehoellein.blogspot.com/2008/02/basic-type-conversions-with-f.html

于 2012-05-23T12:29:26.867 回答
1

FSharp.Interop.Dynamic使用 DLR,因此对于大多数人来说可能有点矫枉过正,但具有Dyn.implicitConvert动态使用 C# 隐式运算符的功能。

   [<Test>] member basic.``Test Implicit Conversion`` ()=
                    let ele = 50
                    ele |> Dyn.implicitConvert |> should equal (decimal 50)
于 2018-04-02T22:22:55.147 回答