"unification" in the understanding of lists

Ok, I'm trying to make a function to determine if a list of tuples is transitive, i.e. if the list contains (x, y) and (y, z), then (x, z) is also in the list.

For example, [(1,2), (2,3), (1,3)] is transitive.

Now, based on the Prolog background, the following makes sense to me:

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

HOWEVER, it does not work. It seems that "y" does not get a single meaning, as I expected, but "reassigned" when it comes to the second tuple. Instead, we should use:

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

Why is this so? Why does the first example not cause an error and does the principle of functional programming languages โ€‹โ€‹contradict "referential transparency?"

"However, in pure functional and logical languages, variables are bound to expressions and retain the same value throughout their lives due to referential transparency requirements." - Wikipedia

Thanks!

+6
source share
1 answer

Even in functional languages, name shading exists. This is sometimes useful. In the first code, (y,z) <- xs shadows y bound (x,y) <- xs before.

Compile with warnings to be warned about such things.

+8
source

Source: https://habr.com/ru/post/913340/


All Articles