Reputation: 1525
I would like to instantiate an anonymous class in F# and define my own hash/equality. Could someone please tell me how?
Specifying Equals/GetHashCode in the interface does not work. It's possible to instantiate the methods, but they cannot then be invoked in any way I can see. Basically, I would like to instantiate the interface IBlah below in a way that gives me an object with the specified hash function. The closest I can get is function "instance" in the testfixture, but that produces and instance that uses the default hash.
I also wondered if someone could tell me how could invoke the "inner" GetHashCode in class impl.
Many thanks in advance.
open NUnit.Framework
type IBlah =
abstract anint : int
abstract GetHashCode : unit -> int
type impl (i:int) =
interface IBlah with
member x.anint = i
member x.GetHashCode () = failwithf "invoked"
//override x.GetHashCode () = i
[<TestFixture>]
type trivial () =
let instance i =
{
new IBlah with
member x.anint = i
member x.GetHashCode () = failwith "It is invoked after all"
}
// this fails (in the comparison, not due to a failwith)
[<Test>]
member x.hash () =
Assert.AreEqual (instance 1 |> hash, instance 1 |> hash)
// this passes if the commented-out override is added, otherwise it fails due to different hashvalues
[<Test>]
member x.hash' () =
Assert.AreEqual (impl 1 |> hash, impl 1 |> hash)
// this passes whether the override is there or not (i.e. no exception is thrown either way)
[<Test>]
member x.hash'' () =
impl 1 :> IBlah |> hash |> ignore
Upvotes: 2
Views: 1693
Reputation: 47904
You'll need to specify obj
(System.Object
) as the first type in your object expression to override GetHashCode
.
type IBlah =
abstract anint : int
let blah =
{ new obj() with
override x.GetHashCode() = 0
interface IBlah with
member x.anint = 0 }
Upvotes: 12