2009-11-11 13 views
9

Esiste qualche nozione sulla qualità del puntatore in Haskell? == richiede che le cose derivino Eq, e ho qualcosa che contiene un valore (Valore -> Valore IO), e né -> né IO derivano Eq.Uguaglianza puntatore in Haskell?

EDIT: Sto creando un interprete per un'altra lingua che fa ha uguaglianza puntatore, quindi sto cercando di modellare questo comportamento, pur essendo in grado di utilizzare le funzioni di Haskell per modellare le chiusure.

EDIT: Esempio: Voglio una funzione special che farebbe questo:

> let x a = a * 2 
> let y = x 
> special x y 
True 
> let z a = a * 2 
> special x z 
False 

risposta

10

EDIT: Dato il tuo esempio, potresti modellare questo con la monade IO. Assegna le tue funzioni agli IORef e confrontale.

Prelude Data.IORef> z <- newIORef (\x -> x) 
Prelude Data.IORef> y <- newIORef (\x -> x) 
Prelude Data.IORef> z == z 
True 
Prelude Data.IORef> z == y 
False 
+0

Voglio solo vedere se due funzioni che sto ottenendo sono in realtà la stessa funzione. Sto cercando di creare un interprete per un'altra lingua che abbia uguaglianza di puntatore e voglio imitare questo comportamento. – Claudiu

+2

Ma cosa significa esattamente "stessa funzione"? (\ x -> x) ha la stessa funzione di (\ x -> x). La stessa funzione di ((\ x y -> y) x), ecc. Penso che quello che ti serve sia un dato aggiuntivo per tracciare l '"indirizzo" di una funzione nella tua lingua interpretata. Una monade che modella un a -> (Int, a) coalgebra potrebbe essere in ordine. – Apocalisp

+1

Purtroppo abbiamo il caso male = ID {unId = const undefined} anche, quindi il tuo esempio non è vero al 100%. Quei fastidiosi fondi. :) – Tirpen

3

IORefs derivano Eq. Non capisco cos'altro è necessario per ottenere l'uguaglianza del puntatore di.

Modifica: le uniche cose che ha senso confrontare l'uguaglianza del puntatore sono strutture mutabili. Ma come ho menzionato sopra, le strutture mutabili, come IORefs, già l'Eq dell'istanza, che consente di vedere se due IORef sono della stessa struttura, che è esattamente l'uguaglianza del puntatore.

+0

scusate, ho risolto la mia domanda. IO non deriva Eq e nemmeno le funzioni. Voglio verificare se due funzioni hanno la stessa funzione. – Claudiu

+0

Ma gli IO non sono "puntatori". Non vedo cosa significherebbe confrontarli. Puoi fare un esempio? – newacct

+0

Non è possibile confrontare due funzioni per vedere se sono uguali. Ad esempio, potrei scrivere "foo x = 2 * x" e "bar x = x + x". Chiaramente foo e bar sono uguali perché per tutti x, foo x == bar x, ma nel caso generale questo è indecidibile. So che non è proprio quello che volevi; vuoi un confronto "potrebbe essere diverse funzioni". Ma no, Haskell non ha questo. –

8

L'uguaglianza del puntatore si interromperà referential transparency, quindi NO.

Sorprendentemente, è in realtà possible calcolare extensional equality delle funzioni complessive in compact spaces, ma in generale (ad esempio le funzioni di interi con possibile non terminazione) questo è impossibile.


EDIT: Sto creando un interprete per un'altra lingua

Si può solo mantenere l'AST programma originale o posizione di origine accanto alle funzioni di Haskell li avete tradotti in? Sembra che tu voglia "l'uguaglianza" basata su questo.

+3

Sono abbastanza sicuro che le espressioni 'extensional ugality' e' compact topology' non sono nel gergo comune. – yfeldblum

+1

le frasi 'extensional ugality' e' compact topology' sono le frasi che mi impediscono di provare haskell –

+0

Link interessante. Il mio primo pensiero fu "questo tipo sta parlando di spazzatura". Ma non stiamo parlando di funzioni generali, stiamo parlando di funzioni _computabili_. Questo fa la differenza. – Thomas

5

== richiede cose da derivare Eq

realtà (==) richiede una un'istanza dell'eq, non necessariamente un derivato esempio. Quello che probabilmente devi fare è fornire la tua istanza di Eq che semplicemente ignora la parte (Value -> IO Value). Ad es.,

data D = D Int Bool (Value -> IO Value) 

instance Eq D where 
    D x y _ == D x' y' _ = x==x && y==y' 

Questo aiuto, forse?

+1

I pensi che tu intenda 'x == x''? – mipadi

+0

lo fa, e l'ho fatto per ora – Claudiu

+1

Sì, 'x == x'' è quello che intendevo. –

3

Sto creando un interprete per un'altra lingua che ha uguaglianza puntatore, quindi sto cercando di modello di questo comportamento, pur essendo in grado di utilizzare le funzioni di Haskell per modellare chiusure.

Sono sicuro che per scrivere un interprete come questo, il tuo codice dovrebbe essere monadico. Non devi mantenere un qualche tipo di ambiente o stato? In tal caso, è possibile anche mantenere un contatore per le chiusure di funzioni. Pertanto, ogni volta che crei una nuova chiusura la equipaggi con un ID unico. Quindi per l'equivalenza del puntatore si confronta semplicemente questi identificatori.

3

Un altro modo per farlo è sfruttare StableNames.

Tuttavia, speciale dovrebbe restituire i suoi risultati all'interno della monade IO a meno che non si voglia abusare di unsafePerformIO.

La soluzione IORef richiede IO per tutta la costruzione della struttura. Checking StableNames lo utilizza solo quando si desidera verificare l'uguaglianza referenziale.

+1

Questa è una soluzione piuttosto buona per controllare l'uguaglianza delle funzioni, anche se 'StableName's non è sempre equivalente quando sembra intuitivo. Volevo solo aggiungere un link ai documenti: http://hackage.haskell.org/package/base-4.7.0.2/docs/System-Mem-StableName.html –