F# 中的扩展运算符

Extension operator in F#

免责声明:我是 F# 的新手。

我创建了一个具有附加功能的自定义类型。我想扩展它以允许使用标准 + 运算符进行添加(为简洁起见简化了类型):

type MyInt = {N:int}

let sumMyInt n1 n2 = {N=n1.N + n2.N}

type MyInt with
    static member (+)(n1, n2) = sumMyInt n1 n2

let n1 = {N=1}
let n2 = {N=2}

printfn "%O" (n1 + n2)

这有效并打印 {N=3}。我想将此操作提升到 MyInt 的列表,并且 if I understand the MSDN docs correctly 扩展 MyInt list 需要扩展方法。所以我写:

open System.Collections.Generic
open System.Runtime.CompilerServices

let sumMyInts = List.map2 sumMyInt

[<Extension>]
type MyIntListExtensions =
    [<Extension>]
    static member inline (+)(ss1, ss2) = sumMyInts ss1 ss2

    [<Extension>]
    static member inline SumMyInts (ss1, ss2) = sumMyInts ss1 ss2


let x = sumMyInts ns1 ns2
let y = ns1.SumMyInts ns2
let z = ns1 + ns2

现在 xy 编译并工作。 z 拒绝编译并出现错误:

The type 'MyInt list' does not support the operator '+'

最令人惊讶的部分是编译:

let z' = ns1.op_Addition ns2

我是不是做错了什么?如何定义扩展运算符?

你今天不能在 F# 中做你想做的事,请参阅 this RFC

可以做的是创建一个执行此操作的全局运算符:

let inline (@+) (xs: 'a list) (ys: 'a list) =
  List.map2 (+) xs ys


> [1; 2] @+ [3; 4]
- ;;
val it : int list = [4; 6]

出于显而易见的原因,这里明确不隐藏 (+):)。 有关在此处创建运算符的更多信息:https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/operator-overloading#creating-new-operators