6

好的,我正在尝试创建一个函数来确定元组列表是否是可传递的,即如果 (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 ]

为什么会这样?为什么第一个示例不会导致错误,这不违反函数式编程语言的“引用透明性”原则吗?

“然而,在纯函数和逻辑语言中,由于引用透明性的要求,变量绑定到表达式并在其整个生命周期内保持一个值。” -维基百科

谢谢!

4

1 回答 1

8

即使在函数式语言中,也存在名称阴影。有时这很有用。在第一个代码中,(y,z) <- xs阴影y(x,y) <- xs之前的约束。

编译时打开警告以提醒此类事情。

于 2012-04-16T17:09:45.643 回答