【问题标题】:Why can't we satisfy F# static member constraints with type extensions?为什么我们不能通过类型扩展来满足 F# 静态成员约束?
【发布时间】:2014-08-17 04:10:37
【问题描述】:

我希望能够使用静态方法从其他库中扩展类型以启用泛型算术。以 Microsoft 新推出的 SIMD 友好的固定大小 VectorN 类型为例。他们定义了Zero,他们定义了(+),他们定义了(/),但我不能在他们身上使用Array.average,因为他们没有定义DivideByInt,我很乐意这样做:

open System.Numerics
type Vector2f with 
  static member DivideByInt (v:Vector2f) (i:int) = v / Vector2f(single i, single i)
let bigArray : Vector2f[] = readABigFile()
printf "the average is %A" (Array.average bigArray)

但它不会让我编译,抱怨

error FS0001: The type 'Vector2f' does not support the operator 'DivideByInt'

为什么在 F# 编译器中存在这个限制?

(编辑:基本上问了同样的问题previously。)

【问题讨论】:

  • 我怀疑DivideByInt 需要是一个运算符而不是一个函数。也许尝试定义一个运算符,或者我认为op_DivideByInt 可能会起作用。
  • DivideByInt 不是 F# 中运算符的有效名称
  • DivideByInt (v:Vector2f,i:int)(元组形式)有效吗?我有一个有效的类型扩展的最小示例。
  • 查看源代码将显示您需要满足的约束:github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/…
  • 不,很遗憾,这是不可能的。 stackoverflow.com/questions/3681142/… 的可能重复项

标签: f# generic-constraints


【解决方案1】:

目前无法在类型扩展中定义运算符重载。对此有一个F# language user voice item(有相当多的选票),因此这可能会在未来的 F# 版本中发生变化(我认为这将是一个很好的补充,非常适合 F# 设计)。

如果你今天绝对需要这样的东西,你可以为你的类型创建一个轻量级的包装器来添加运算符,或者你可以使用一个(有点可怕的)技巧,让你用一个新的重载运算符隐藏标准运算符。以下问题有两个例子:Global operator overloading in F#

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 2019-09-19
    • 2022-08-06
    相关资源
    最近更新 更多