F# container that implements equality only when underlying type does -
edit: appears answer , comment added far have not explained want. here example:
// type not supporting type of comparison [<noequality>] [<nocomparison>] type blah () = member x.huha = 0 // make map, turns out work whether x supports equality or not let inline tt x = map.oflist [1, x] let test () = // maps can compared equality if argument can if (tt 1 = tt 2) failwithf "strange" // maps can made no matter if argument supports equality if (tt (blah ())).count <> 1 failwithf "size" // not compile if tt (blah ()) = tt (blah ()) ....
in short, want own type behave map above. should support equality when type argument does, , should not when type argument doesn't. want typechecker stop me using equality when not supported, seeing can builtin types. again.
original question: various built-in f# types support equality if , if underlying type does. example, map<'k, 'd>
support equality iff 'd
(and detected @ compile-time). possible implement behaviour in user-code? here 1 failed attempt, , version compiles fine if equality unconditional. many thanks.
[<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
you have part of solution already: using [<equalityconditionalon>]
on generic parameter.
the part missing: need use unchecked.equals
instead of normal =
operator within map implementation (anywhere you're checking equality of 2 'a
values). unchecked.equals
checks @ run-time whether type supports generic equality. if does, compares 2 instances/values equality usual; if not, falls structural equality check or type's implementation of object.equals(obj)
method.
Comments
Post a Comment