The standard =
operator assumes that both of the arguments have the same type, so I think there is no way to add an overload that works on different types. I think a sensible alternative might be to define a pair of operators .=
and =.
(similar operators e.g. .*
and *.
are often used for scalar multiplication with scalar on the left and right, respectively):
type Foo(n:int) =
member x.N = n
static member (=.) (x:Foo, y:int) = x.N = y
static member (.=) (y:Foo, x:int) = x.N = y
But perhaps it is better to just ask the user to write a.N = y
explicitly when they want to compare two values of different types (because, strictly speaking, two values of the same type can never be equal - they are not even of the same type!)
If you really wanted to, you could re-define the =
operator, but I would not recommend that (and, when you define the operator (=)
using let
, the compiler gives you a warning saying that this is normally not recommended). Anyway, it could be done using a trick described e.g. here:
type Foo(n:int) =
member x.N = n
// A type that contains all overloads of the `=`
// operator that you want to support
type Equality = EQ with
static member (?<-) (_:Equality, x:int, y:int) = x = y
static member (?<-) (_:Equality, x:float, y:float) = x = y
static member (?<-) (_:Equality, x:Foo, y:int) = x.N = y
// This hides the standard equality operator and can
// lead to all sorts of confusion! (Probably do not do this :-))
let inline (=) x y = (?<-) EQ x y
10 = 4
Foo(10) = 3
Perhaps you could define your own operator using the method described in the latter part of the answer, but do not hide =
and instead call it differently. Then you could handle overloads (as well as standard types) but you would not hide the standard definition.