2012-04-16 14 views
6

Ok, ich versuche, eine Funktion zu machen, um festzustellen, ob eine Liste von Tupeln transitiv ist, dh wenn (x, y) und (y, z) in der Liste ist, dann (x , z) ist auch in der Liste.'Vereinheitlichung' in Liste Comprehensions

Zum Beispiel ist [(1,2), (2,3), (1,3)] transitiv.

Nun, von einem Hintergrund Prolog kommt, folgenden Sinn für mich:

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

JEDOCH funktioniert es nicht. Es scheint, dass das 'y' nicht wie erwartet den Einzelwert erhält, sondern im zweiten Tupel "neu zugewiesen" wird. Stattdessen müssen wir verwenden:

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

Warum ist das so? Warum verursacht das erste Beispiel keinen Fehler und widerspricht dies nicht dem Prinzip der referentiellen Transparenz der funktionalen Programmiersprachen?

"In reinen funktionalen und logischen Sprachen sind Variablen jedoch aufgrund ihrer referenziellen Transparenz während der gesamten Lebensdauer an Ausdrücke gebunden und behalten einen einzigen Wert." - Wikipedia

Danke!

+0

Bitte lernen Sie, Ihren Code zu formatieren. – Marcin

+0

Will do, meine Entschuldigung – Jarmex

+0

Keine Entschuldigung - SO ist nicht wirklich eine gute Arbeit der Warnung neuer Benutzer, dass sie das tun müssen, so dass fast jeder neue Benutzer irgendwann erzählt werden muss. – Marcin

Antwort

8

Auch in funktionalen Sprachen gibt es Namen Shadowing. Manchmal ist das nützlich. Im ersten Code, der (y,z) <- xs Schatten der y gebunden durch die (x,y) <- xs vor.

Kompilieren Sie die Warnungen, die aktiviert sind, um auf solche Dinge hingewiesen zu werden.

+3

Danke dafür, nachdem Sie den Ausdruck 'Shadowing' verwendet haben, fand ich eine sehr ähnliche Frage wurde bereits beantwortet. http://stackoverflow.com/questions/4053789/variables-in-haskell. Vielen Dank für Ihre Zeit :) – Jarmex

Verwandte Themen