'унификация' в списках

Хорошо, я пытаюсь создать функция для определения того, является ли список кортежей транзитивным, т. е. если (x,y)и (y,z)есть в списке, то (x,z)также есть в списке. список.

Например, [(1,2), (2,3), (1,3)]транзитивно.

Теперь, исходя из фона Пролога, следующее имеет смысл для меня:

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

ОДНАКО, это не работает. Похоже, что «y» не получает единственного значения, как я ожидал, но «переназначается», когда дело доходит до второго кортежа. Вместо этого мы должны использовать:

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

Почему это так? Почему первый пример не вызывает ошибки и не противоречит ли это принципу «реляционной прозрачности» функциональных языков программирования?

«Однако в чисто функциональных и логических языках переменные связаны с выражениями и сохраняют одно значение в течение всего времени их существования из-за требований ссылочной прозрачности».-Википедия

Спасибо!

6
задан Marcin 16 April 2012 в 17:09
поделиться