Generics 通用F#运算符

Generics 通用F#运算符,generics,f#,type-inference,Generics,F#,Type Inference,此问题遵循此处发布的想法: 我开始怀疑,是否可以定义一个以类似方式接受两个参数的泛型运算符,就像我链接的帖子中介绍的那样 例如:我一直在尝试实现一个“AlmostEqual”操作符(=~),它可以处理浮点数和我自己的类型,称为“VectorDirection”。 根据这个想法,我创建了以下代码: type AlmostEqual = AlmostEqual with static member ($) (AlmostEqual, (a,b) : float * float) = a &

此问题遵循此处发布的想法:

我开始怀疑,是否可以定义一个以类似方式接受两个参数的泛型运算符,就像我链接的帖子中介绍的那样

例如:我一直在尝试实现一个“AlmostEqual”操作符(=~),它可以处理浮点数和我自己的类型,称为“VectorDirection”。 根据这个想法,我创建了以下代码:

type AlmostEqual = AlmostEqual with
    static member ($) (AlmostEqual, (a,b) : float * float) = a >= b - Math.tol && a <= b + Math.tol    
    static member ($) (AlmostEqual, (vd1, vd2)) =
                        // my logic goes here - irrelevant for the general idea presented here

let inline (=~) x = AlmostEqual $ x
这意味着更自然的使用方式:

arg1 =~ arg2  // wrong: (=~) complains it's in a wrong place and arg2 is not a tuple
这是不允许的。我理解它的局限性,但我真的找不到一种方法来绕过它

let inline (=~) (x,y) = ...
是否有一个函数以元组为参数

let inline (=~) x y = ...
函数有两个参数。 如果要将函数用作中缀函数,则需要接受两个参数

是否有一个函数以元组为参数

let inline (=~) x y = ...
函数有两个参数。
如果要将函数用作中缀函数,则需要使用两个参数。

如另一个答案中所述,问题是元组参数与当前参数,通过这样定义函数将解决主要问题:

let inline (=~) x y = AlmostEqual $ (x, y)
无论如何,我建议您也更改成员定义,因为通过对多态参数进行元组化,您可能会遇到重载解析问题。如果遇到这些问题,请尝试以下方法:

type AlmostEqual = AlmostEqual with
    static member ($) (AlmostEqual, a: float) = fun (b: float) -> // {your implementation}
    static member ($) (AlmostEqual, vd1     ) = fun vd2        -> // {your implementation}

let inline (=~) x y = (AlmostEqual $ x) y

正如在另一个答案中所解释的,问题是元组参数与curried参数,通过这样定义函数将解决主要问题:

let inline (=~) x y = AlmostEqual $ (x, y)
无论如何,我建议您也更改成员定义,因为通过对多态参数进行元组化,您可能会遇到重载解析问题。如果遇到这些问题,请尝试以下方法:

type AlmostEqual = AlmostEqual with
    static member ($) (AlmostEqual, a: float) = fun (b: float) -> // {your implementation}
    static member ($) (AlmostEqual, vd1     ) = fun vd2        -> // {your implementation}

let inline (=~) x y = (AlmostEqual $ x) y