user1002059
user1002059

Reputation: 1525

anonymous class in F#

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

Answers (1)

Daniel
Daniel

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

Related Questions