2012-04-16 4 views
6

Ok, sto tentando di fare una funzione per determinare se un elenco di tuple è transitivo, cioè se (x, y) e (y, z) sono nella lista, quindi (x , z) è anche nella lista.'unificazione' in list comprehensions

Ad esempio, [(1,2), (2,3), (1,3)] è transitivo.

Ora, venendo da un background Prolog, il seguente senso per me:

transitive xs = and [elem (x, z) xs | (x, y) <- xs , (y, z) <- xs ] 

tuttavia, non funziona. Sembra che la 'y' non abbia il singolo valore come mi aspetterei, ma è 'riassegnata' quando si tratta della seconda tupla. Invece, dobbiamo usare:

transitive xs = and [elem (x, z) xs | (x, y1) <- xs , (y2, z) <- xs, y1 == y2 ] 

Perché è così? Perché il primo esempio non causa un errore, e questo non va contro il principio di "trasparenza referenziale" dei linguaggi di programmazione funzionale?

"Tuttavia, in puro linguaggio funzionale e logico, le variabili sono legate alle espressioni e mantengono un singolo valore durante l'intera vita a causa dei requisiti di trasparenza referenziale." - Wikipedia

Grazie!

+0

Si prega di imparare a formattare il codice. – Marcin

+0

Lo farò, mi scuso – Jarmex

+0

Non c'è bisogno di scusarmi - SO in realtà non fa un buon lavoro di avvertire i nuovi utenti che hanno bisogno di farlo, quindi quasi ogni singolo nuovo utente deve essere detto a un certo punto. – Marcin

risposta

8

Anche in lingue funzionali, c'è il nome shadowing. A volte è utile. Nel primo codice, lo (y,z) <- xs ombreggia lo vincolato dallo (x,y) <- xs in precedenza.

Compilare con avvisi attivati ​​per essere avvisati di queste cose.

+3

Grazie per questo, dopo aver usato la frase "shadowing", ho trovato una domanda molto simile a già stato risposto http://stackoverflow.com/questions/4053789/variables-in-haskell. Grazie per il tuo tempo :) – Jarmex