编辑:从迄今为止的答案和评论来看,我似乎没有正确解释我的要求。这里有一个例子:
// type not supporting any type of comparison
[<NoEquality>]
[<NoComparison>]
type blah () =
member x.huha = 0
// make a map, turns out to work whether x supports equality or not
let inline tt x =
Map.ofList [1, x]
let test () =
// maps can be compared for equality if the argument can
if (tt 1 = tt 2) then failwithf "strange"
// maps can be made no matter if the argument supports equality
if (tt (blah ())).Count <> 1 then failwithf "size"
// this does not compile
if tt (blah ()) = tt (blah ()) then ....
简而言之,我希望我的自定义类型能够像上面的 map 一样行为。因此,当类型参数支持时,它应该支持相等性,否则不应该支持相等性。我还希望类型检查器在不支持相等性时阻止我使用相等性,就像对内置类型明确可以做到的那样。再次感谢。
原问题:各种内置的 F# 类型仅在某些基础类型支持时才支持相等性。例如,Map<'k,'d> 当且仅当 'd 支持时才支持相等性(并且这在编译时被检测)。是否可能在用户代码中实现此行为?以下是一个失败的尝试和一个版本,如果相等性无条件,则可以编译通过。非常感谢。
[<NoComparison>]
type test_fails<[<EqualityConditionalOn>]'a> (content:'a) =
let eq_impl (x:test_fails<'a>) (y:obj) =
let y = y :?> test_fails<'a>
x.content = y.content
member x.content = content
override x.Equals (y:obj) =
eq_impl x y
[<NoComparison>]
type test_compiles<'a when 'a : equality> (content:'a) =
let eq_impl (x:test_compiles<'a>) (y:obj) =
let y = y :?> test_compiles<'a>
x.content = y.content
member x.content = content
override x.Equals (y:obj) =
eq_impl x y
equality
约束是必要的,因为您使用的是=
。 - Danielthis.Equals
)。 - Søren Debois