F#容器,仅当底层类型执行相等时才实现相等

F#容器,仅当底层类型执行相等时才实现相等,f#,F#,编辑:从迄今为止添加的答案和评论来看,我没有正确解释我想要什么。以下是一个例子: // 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

编辑:从迄今为止添加的答案和评论来看,我没有正确解释我想要什么。以下是一个例子:

// 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 ....

正如Daniel评论的那样,您的问题是
eq_impl
x.content
y.content
上使用
=
,这意味着它们必须支持相等。也许您想改用
Object.ReferenceEquals
?这将取决于您正试图做什么。

您已经有了部分解决方案:在通用参数上使用
[]


缺少的部分:您需要在map实现中使用而不是普通的
=
操作符(在检查两个
'a
值相等的任何地方)
未选中。equals在运行时检查类型是否支持泛型相等。如果是,它会像往常一样比较两个实例/值是否相等;如果没有,则返回到结构相等检查或方法的类型实现。

需要
相等
约束,因为您使用的是
=
。我认为使用基本相等主要是拥有[]的目的?显然,我不知道如何正确地做。杰克·P.的答案完全正确。看看在(搜索
this.Equals
)中是如何完成的。我现在添加了一个示例来更好地解释我想要什么。非常感谢。
[<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