在多种类型上推广一个新的运算符

时间:2012-07-02 16:54:11

标签: f# typeclass functor generic-programming f#-unquote

我正在使用Unquote并且没有看到任何近似的内容。 所以我决定写一个。

let inline (=~=) x y = abs x-y <  1.E-10

然而,运营商没有映射到Lists

let test  = [1;2] =~= [1;2]  //---> error

是否可以将此运算符声明为(=)

或者它是否需要定义像'StructuralEquality-ishness'这样的新特征?

使用http://code.google.com/p/fsharp-typeclasses/

定义一个新的运算符是否更好?

2 个答案:

答案 0 :(得分:5)

我不知道Unquote,但关于近似函数/运算符,我不确定是否有办法通过结构比较来实现它。

如果你想“手动”,使用类似于F#Typeclasses项目的技术(或技巧),这里有一个例子:

type Approximate = Approximate with
    static member inline ($) (Approximate, x:^n       ) = fun (y:^n) -> float (abs (x-y)) <  1.E-10
    static member inline ($) (Approximate, x:list< ^n>) = 
        fun (y:list< ^n>) -> 
            x.Length = y.Length && (List.zip x y |> List.forall ( fun (a,b) -> (Approximate $ a) b))
// More overloads
let inline (=~=) x y = (Approximate $ x) y

答案 1 :(得分:3)

(我没有使用过Unquote,所以这可能不适用。)

看一下你的功能签名

'a -> 'b -> bool (requires member ( - ) and member Abs)

List不支持其中任何一个运算符。是的,您的函数是通用的,但约束条件不允许它与列表一起使用。

另一方面,

(=)没有约束,这意味着它可以用于任何类型。如果你的函数可以被重写以删除约束,那么它可以被类似地使用(但我不知道考虑使用-abs这是怎么可能的 - 你怎么期望{{1与这些运算符一起行动?)。