f# - 无法在 F# 中扩展运算符?

标签 f# operators extension-methods

module FSharp=
let Point2d (x,y)= Point2d(x,y)
let Point3d (x,y,z)= Point3d(x,y,z)
type NXOpen.Point3d with
    static member ( * ) (p:Point3d,t:float)= Point3d(p.X*t,p.Y*t,p.Z*t)
    static member ( * ) (t:float,p:Point3d)= Point3d(p.X*t,p.Y*t,p.Z*t)
    static member (+) (p:Point3d,t:float)= Point3d(p.X+t,p.Y+t,p.Z+t)
    static member (+) (t:float,p:Point3d)= Point3d(p.X+t,p.Y+t,p.Z+t)
    static member (+) (p:Point3d,t:Point3d)= Point3d(p.X+t.X,p.Y+t.Y,p.Z+t.Z)

let a=Point3d (1.,2.,3.)
let b=1.0
let c=a * b//error

Error 15: The type 'float' does not match the type
'Point3d' E:\Work\extension-RW\VS\extension\NXOpen.Extension.FSharp\Module1.fs 18 13 NXOpen.Extension.FSharp

我想扩展 Point3d 方法,一些新的操作符。但它并没有过去。

最佳答案

如果 Point3d 类型在您无法修改的单独程序集中声明,那么(不幸的是)没有办法实现像 +*。您问题中的代码将运算符添加为扩展方法,但 F# 编译器在查找重载运算符时不会搜索扩展方法。

如果你不能修改库,那么你可以做三件事:

  • Point3d 创建一个包装器,该包装器存储 Point3d 的值并实现所有运算符
    (但这可能会非常低效)

  • 定义不与内置运算符冲突的新运算符。例如,您可以使用 +$$+ 进行从左到右的标量相乘。要声明这样的运算符,您可以编写:

    let (+$) (f:float) (a:Point3d) = (...)
    
  • 实现你自己的 Point3d 类型来完成所有工作,当你需要调用一个库时,可能使用转换函数将其转换为 Point3d

很难说哪个选项最好 - 第二种方法可能是最有效的,但它会使代码看起来有点难看。根据您的情况,选项 1 或 3 也可能有效。

关于f# - 无法在 F# 中扩展运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8309620/

相关文章:

arrays - F# - 将数组转换为列表

list - F#创建x的倍数列表?

python - Python 中 % 的结果是什么?

c# - 使 LINQ 扩展方法应用于我的类

f# - 抽象方法的语法是什么?

asynchronous - F#异步-两种结构之间的区别

c# - 为什么在这个例子中 "x ^= true"会产生 false?

c++ - 运算符重载的基本规则和惯用法是什么?

reflection - 将 List<Type> 转换为 List<Type B>

c# - 在 C# 中操作密封类型