2012-06-09 14 views
8

Ho un tipo di record che include una funzione:uguaglianza strutturale in F #

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

voglio questo tipo di avere l'uguaglianza strutturale. C'è un modo in cui posso semplicemente segnalare che lo bar dovrebbe essere ignorato nei test di uguaglianza? O c'è un altro modo per aggirare questo?

risposta

17

Vedere il messaggio di Don's blog su questo argomento, in particolare la sezione Uguaglianza personalizzata e confronto.

L'esempio che dà è quasi identica alla struttura record che si propone:

/// 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" 
7

Per rispondere più specificamente tua domanda iniziale, è possibile creare un tipo personalizzato il cui confronto tra le istanze è sempre vero:

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

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

    override x.GetHashCode() = 0 

type MyType = { 
    foo: int; 
    bar: StructurallyNull<int -> int> 
} 
+1

+1 creativo :-) –