我试图覆盖(=)以便能够将我新定义的类型与int进行比较。我想要实现这个湖:
type T = T with static member op_Equality (_ : T, c : int) = true
let b = T = 2 // Error: This expression was expected to
// have type T but here has type int
我可以轻松地在C#中使用它,但不能在F#
中执行此操作我也试过
我想知道是否可以让(=)运算符完全使用两种不同的类型?
答案 0 :(得分:2)
标准=
运算符假定两个参数具有相同的类型,因此我认为无法添加适用于不同类型的重载。我认为一个明智的选择可能是定义一对运算符.=
和=.
(类似运算符,例如.*
和*.
通常用于标量乘法,左边是标量和对,分别):
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
但也许最好只要求用户在想要比较不同类型的两个值时明确地写a.N = y
(因为严格来说,相同类型的两个值永远不能相等 - 它们是甚至不是同一类型!)
如果您真的想要,可以重新定义=
运算符,但我不建议(并且,当您使用(=)
定义运算符let
时,编译器给你一个警告,说这通常不推荐)。无论如何,可以使用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
也许您可以使用答案后半部分中描述的方法定义自己的运算符,但不要隐藏=
,而是以不同方式调用它。然后你可以处理重载(以及标准类型),但你不会隐藏标准定义。