简体   繁体   中英

Generic F# operators fun

This question follows the idea posted here: Generic units in F#

I've started wondering if that was possible to define a generic operator that accepts two arguments in a similar way, like it it presented in the post I linked ?

For exapmple: I've been trying to implement an "AlmostEqual" operator (=~) that works with Floats and my own type, called "VectorDirection". Following the idea, I've created the following piece of code:

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

That works fine, BUT with a serios limitation: it can be used in the following way:

(=~) (arg1, arg2)

That means the more natural way of using it:

arg1 =~ arg2  // wrong: (=~) complains it's in a wrong place and arg2 is not a tuple

is not allowed. I understand the limitation, but I can't really find a way to walk it around.

let inline (=~) (x,y) = ...

are a function there takes a tuple as its argument and

let inline (=~) x y = ...

are a function there takes two arguments. If you want to use a function as a infix function it need to take two arguments.

As explained in the other answer the problem is tupled vs. curried arguments, by defining your function like this will solve the main issue:

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

Anyway I would advise you to change your members definition as well, because you may have problems with overload resolution by tupling the polymorphic arguments. If you run into these problems try this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM