好的,我正在尝试创建一个函数来确定元组列表是否是可传递的,即如果(x,y)和(y,z)在列表中,那么(x,z)也在清单。
例如,[(1,2), (2,3), (1,3)]
是可传递的。
现在,来自Prolog背景,以下内容对我有意义:
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 ]
为什么会这样?为什么第一个例子不会导致错误,这是否违背了函数式编程语言的“引用透明度”原则?
“然而,在纯函数式和逻辑式语言中,由于引用透明性的要求,变量被绑定到表达式并在其整个生命周期中保持单个值。” - Wikipedia
谢谢!
答案 0 :(得分:8)
即使在函数式语言中,也存在名称阴影。有时这很有用。
在第一个代码中,(y,z) <- xs
隐藏了y
之前绑定的(x,y) <- xs
。
在打开警告的情况下编译以提醒这些事情。