Question

I have the following discriminated union:

type ActCard = Cellar of card list 
                | Chapel of (card option * card option* card option* card option) 
                | Smithy | Spy of (card -> bool * card -> bool)

It had structural equality until I added the card -> bool to Spy. This question is helpful for how to do custom equality for records. However, I'm not sure how best to implement it in this situation. I would prefer to not have to enumerate each case in ActCard:

override x.Equals(yobj) =
    match x, yobj with
    |  Spy _, Spy _ -> true
    |  Cellar cards, Cellar cards2 -> cards = cards2
    (* ... etc *)

What is a better approach here?

Was it helpful?

Solution

There isn't a better approach. If you're not going to use the default structural equality you'll have to spell out equality semantics.

EDIT

You could do something like this.

[<CustomEquality; CustomComparison>]
type SpyFunc = 
  | SpyFunc of (card -> bool * card -> bool) 
  override x.Equals(y) = (match y with :? SpyFunc -> true | _ -> false)
  override x.GetHashCode() = 0
  interface System.IComparable with
    member x.CompareTo(y) = (match y with :? SpyFunc -> 0 | _ -> failwith "wrong type")

type ActCard = 
  | Cellar of card list 
  | Chapel of (card option * card option * card option * card option) 
  | Smithy 
  | Spy of SpyFunc
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top