Question

I have a record type that includes a function:

{foo : int; bar : int -> int}

I want this type to have structural equality. Is there some way I can just mark that the bar should be ignored in equality tests? Or is there some other way around this?

Was it helpful?

Solution

See Don's blog post on this topic, specifically the section Custom Equality and Comparison.

The example he gives is almost identical to the record structure you propose:

/// A type abbreviation indicating we’re using integers for unique stamps on objects
type stamp = int
 
/// A type containing a function that can’t be compared for equality  
 [<CustomEquality; CustomComparison>]
type MyThing =
    { Stamp: stamp;
      Behaviour: (int -> int) } 
 
    override x.Equals(yobj) =
        match yobj with
        | :? MyThing as y -> (x.Stamp = y.Stamp)
        | _ -> false
 
    override x.GetHashCode() = hash x.Stamp
    interface System.IComparable with
      member x.CompareTo yobj =
          match yobj with
          | :? MyThing as y -> compare x.Stamp y.Stamp
          | _ -> invalidArg "yobj" "cannot compare values of different types"

OTHER TIPS

To answer more specifically your original question, you can create a custom type whose comparison between instances is always true:

[<CustomEquality; NoComparison>]
type StructurallyNull<'T> =
    { v: 'T } 

    override x.Equals(yobj) =
        match yobj with
        | :? StructurallyNull<'T> -> true
        | _ -> false

    override x.GetHashCode() = 0

You can then use it this way:

type MyType = { 
    foo: int; 
    bar: StructurallyNull<int -> int> 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top