.net F#-如何使用get#u Zero扩展一个类型,以便通用地使用现有类型?

.net F#-如何使用get#u Zero扩展一个类型,以便通用地使用现有类型?,.net,f#,complex-numbers,.net,F#,Complex Numbers,我尝试以下几点: let c x = System.Numerics.Complex(x, 0.0) let sum = [c 1.0; c 2.0] |> List.sum module ComplexExtension = let c x = System.Numerics.Complex(x, 0.0) type System.Numerics.Complex with // I also tried a bunch of other ways o

我尝试以下几点:

let c x = System.Numerics.Complex(x, 0.0)
let sum = [c 1.0; c 2.0] |> List.sum
module ComplexExtension =
    let c x = System.Numerics.Complex(x, 0.0)

    type System.Numerics.Complex with
        // I also tried a bunch of other ways of writing these
        // as static or instance members, but nothing worked
        static member Zero = c 0.0
        static member One = c 1.0

open ComplexExtension

let sum = [c 1.0; c 2.0] |> List.sum
但我得到了这个错误:

类型“System.Numerics.Complex”不支持运算符“get\u Zero”

我从中阅读了有关类型扩展的规则,并尝试执行以下操作:

let c x = System.Numerics.Complex(x, 0.0)
let sum = [c 1.0; c 2.0] |> List.sum
module ComplexExtension =
    let c x = System.Numerics.Complex(x, 0.0)

    type System.Numerics.Complex with
        // I also tried a bunch of other ways of writing these
        // as static or instance members, but nothing worked
        static member Zero = c 0.0
        static member One = c 1.0

open ComplexExtension

let sum = [c 1.0; c 2.0] |> List.sum
我还是会犯那个错误


是否可以使用get_Zero运算符扩展类型?或者我必须围绕
System.Numerics.Complex
创建自己的包装类型,并覆盖所有运算符,如果我想让它做复数所做的其他事情的话?

列表。sum
不能识别定义为扩展的
零。它必须是该类型的一部分

使用
列表。折叠

let sum = [c 1.0; c 2.0] |> List.fold (+) Complex.Zero

顺便说一句,System.Numerics.Complex实际上有一个静态的
Zero
,但它是一个字段,而不是一个属性。

列表。sum
使用静态成员约束。静态成员约束不研究扩展方法,因此这不是一个选项

包装整个复杂类型是一个选项,但这太过了,如果它只是一个特定的调用,那么您有很多方法可以通过几次击键来计算总和,您可以使用
折叠
,如另一个答案所示。或者,如果您确定列表始终至少有一个元素,则可以使用
List.reduce(+)

这可能在未来版本的F#中得到修复,但问题是静态成员约束不适用于字段,除非它们具有getter。然而,在F#lib中,它们可以为现有类型“模拟”这些成员,否则它将无法使用
int
float
,因为它们也没有该成员

我不确定
Complex
这一事实是否是在
系统中定义的。数字
是不以这种方式实现它的原因,或者可能是他们忘记了它。在任何情况下,您都可以打开一个问题或提交一个请求来修复它


最后,如果您仍然希望以通用方式使用它,另一个选项是重新定义
sum
函数。例如,最新版本的
sum
函数(这里是)可以很好地处理几乎所有的数字类型(它有相同的问题,但很容易修复,实际上是一个bug),包括
Complex
和大多数第三方数字类型,因为它有一种回退机制,当类型没有
get_Zero
成员时,这种机制依赖于某些转换。

是的,可能创建包装器是一种方法。请看这里:您正在寻找的东西被称为“高级多态性”,不幸的是,F#一般不支持它。这是一个用户语音请求,请投票: