无论如何可以使用 F# 中的 C# 隐式运算符

本文关键字:运算符 中的 可以使 无论如何 | 更新日期: 2023-09-27 18:35:00

如果我有一个隐式转换为双精度的 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'

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

无论如何可以使用 F# 中的 C# 隐式运算符

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# 中进行隐式转换的主要原因是,这将使类型推断更加困难,并且编译器很难给出良好的错误消息。

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

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

FSharp.Interop.Dynamic 使用 DLR,所以对于大多数人来说可能矫枉过正,但有一个函数Dyn.implicitConvert用于动态使用 C# 隐式运算符。

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