Search code examples
f#websharper

WebSharper: opaque type with equality checking for `===`


I need a datatype that will be completely opaque in F# with equality defined in terms of JS ===. WebSharper manual says that I should override Equals but I can't make it work.

let x : OpaqueType = X<_>

let f (y : OpaqueType) =
    if x = y then // this line should be translated to `if (x === y)`
        42
    else
        10

So, what is the correct definition of OpaqueType?

Of course, I can use obj and add an inline function that will do x === y but I'd like to have something more awesome.


Solution

  • I would go for something like this:

    module Test =
        open IntelliFactory.WebSharper
    
        [<JavaScript>]
        let Counter = ref 0
    
        [<Sealed>]
        [<JavaScript>]
        type T() =
    
            let hash =
                incr Counter
                Counter.Value
    
            [<JavaScript>]
            override this.GetHashCode() =
                hash
    
            [<JavaScript>]
            override this.Equals(other: obj) =
                other ===. this
    
    
        [<JavaScript>]
        let Main () =
            let a = T()
            let b = T()
            JavaScript.Log(a, b, a = b, a = a, hash a, hash b)
    

    Equality and hashing are expected to be consistent by .NET libraries (for example, for use in Dictionary). They are also associated with types through virtual methods, so inlining will not work correctly. The above code gives you a type with reference-like equality semantics.