2010-04-21 10 views
5

In F #, l'operatore di uguaglianza (=) è generalmente estensionale, piuttosto che intensionale. È fantastico! Sfortunatamente, mi sembra che F # non usi l'uguaglianza tra puntatori per abbreviare questi confronti estensionali.controllo di uguaglianza breve in F #?

Per esempio, questo codice:

 
type Z = MT | NMT of Z ref 

// create a Z: 
let a = ref MT 
// make it point to itself: 
a := NMT a 

// check to see whether it's equal to itself: 
printf "a = a: %A\n" (a = a) 

... mi dà un grosso errore di grasso di segmentazione [*], nonostante il fatto che 'a' e 'un' sia restituiscono lo stesso riferimento. Non è così bello. Altri linguaggi funzionali (ad esempio lo schema PLT) ottengono questo diritto, utilizzando i confronti dei puntatori in modo conservativo, per restituire 'true' quando può essere determinato utilizzando un confronto tra puntatori.

Quindi: accetto il fatto che l'operatore di uguaglianza di F # non usi il taglio corto; c'è un modo per eseguire un controllo di uguaglianza intensionale (basato sul puntatore)? L'operatore (==) non è definito sui miei tipi e mi piacerebbe se qualcuno potesse dirmi che è disponibile in qualche modo.

O dirmi che ho sbagliato nella mia analisi della situazione: Mi piacerebbe che, anche ...

[*], che sarebbe probabilmente un overflow dello stack su Windows; ci sono cose su Mono che non mi piacciono molto ...

risposta

7

Ci sono due opzioni di cui sono a conoscenza. L'approccio standard .NET potrebbe essere quello di utilizzare System.Object.ReferenceEquals. Un approccio leggermente migliore in F # potrebbe essere quello di utilizzare LanguagePrimitives.PhysicalEquality che è sostanzialmente identico, ma funziona solo sui tipi di riferimento (che è probabilmente corretto per i propri scopi) e richiede che entrambi gli argomenti abbiano lo stesso tipo statico. Puoi anche definire un operatore personalizzato di tua scelta in termini di una di queste funzioni se desideri una sintassi migliore.

Per inciso, su .NET ottengo un ciclo infinito ma non un sovraccarico di stack quando eseguo il codice, presumibilmente a causa dell'ottimizzazione delle chiamate tail.

+0

Grazie! Per inciso: sì, questo in realtà esegue il dump di core su mono/osx. Forse il tail-calling non è implementato correttamente per il controllo di uguaglianza nella particolare combinazione di mono/fsharp che sto usando. –