我必须确定函数s1和s2的自由和有界变量的集合:
s1 := \x -> if y then \z -> (x \y -> y) else (\z -> w) x
所以,对于s1,我会写:
FV(s1):= FV (y) ∪ FV (x) ∪ FV (w)
我说错了吗?或者它应该是:
FV(s1):= FV (y) ∪ FV (x) ∪ FV (y) ∪ FV (w) ∪ FV (x)
因为y和x是两次免费的。 一旦y in If然后结果 - > ÿ 对于x:x在\ z的结果中是自由一次,在结尾是第二个。
有界变量将是:
BV(s1):= BV (x) ∪ BV (z) ∪ BV (y) ∪ BV (z)
因为z出现两次有界var。
以同样的方式我确定s2的FV和BV:
s2 := let f x1 x2 = y1 (\x -> x2) in let y1 = f w (f y2 y2), y2 = y1 in f
FV(s2):= FV (y1) ∪ FV (x2) ∪ FV (w) ∪ FV (y1)
BV(s2):= BV (f) ∪ BV (x1) ∪ BV (x2) ∪ BV (x) ∪ BV (y1)
你能告诉我我是对还是错?
提前致谢
答案 0 :(得分:2)
自由变量和约束变量的经验法则是,自由变量的值会影响表达式的值。
举一个简单的例子,如果我定义identity x = x
并单独说x = 6
,则不会改变identity 10
为10
的事实;在identity x = x
中,变量x
被绑定,因为它只代表任何输入。我们可以在不改变函数含义的情况下编写identity y = y
。
相反,如果我们定义gimmez x = z
,则z
不受约束。如果我们单独说z = 6
,那么gimmez
会做一些与我们说z = putStrLn "zed zed zed zed can you tell I'm British?"
或gimmez x = zz
截然不同的事情。在任何一种情况下,函数gimmez
都已更改 - z
未绑定。
我是否可以在不更改含义的情况下为varname
查找并替换othervarname
?
varname
受约束。 varname
在表达式中显示为空闲。让我们看看你的实际例子
s1 := \x -> if y then \z -> (x \y -> y) else (\z -> w)
您撰写了FV(s1):= FV (y) ∪ FV (x) ∪ FV (w)
或FV(s1):= FV (y) ∪ FV (x) ∪ FV (y) ∪ FV (w) ∪ FV (x)
让我们依次看看所有变量
\x ->
将lambda范围的x
绑定到行尾。它根本不是一个自由变量。y
在if
之后是免费的,但绑定在无效的表达式(x \y -> y)
中。该括号中的第二个匹配项具有绑定y的值,而不是自由的值。对其他自由变量的删除称为阴影。 y
在表达式中是免费的,但仅仅是因为它的第一次出现。z
绑定在最终的lambda表达式中。w
不受任何限制 - 它是免费的。 摘要: y
和z
是免费的。 x
和z
绑定,y
被遮蔽 - 它也会在表达式的后面作为绑定变量出现。 FV(s1) = {y,z}
和BV(s1)={x,z,y}
我不同意使用符号FV(s1):= FV (y) ∪ FV (w)
。这表明要查找s1
的自由变量,我应该查看y
和w
的自由变量。我不同意 - y
和z
是 s1
的自由变量。确实,如果我想获得定义s1
的模块的自由变量,我需要添加FV (y) ∪ FV (w)
,但这是一个不同的问题。
(符号∪
表示设置联合。事物在集合中或集合之外,您不需要多次添加它们。)
s2 := let f x1 x2 = y1 (\x -> x2) in let y1 = f w (f y2 y2), y2 = y1 in f
let f x1 x2 =
绑定f
,x1
和x2
,即使f
感觉不同;它们都引入了一个新变量,它会影响任何具有相同名称的外部定义,并且在表达式中查找和替换它们不会改变它的含义,因此它们受到约束。
f
,x1
,x2
受let
约束。y1
第一次出现时是免费的 - 第二个let
绑定不在此范围内。x
受lambda y1
现在受let
约束(更多阴影)w
是免费的y2
一开始看起来自由,但实际上是在y2 = y1
FV(s2):= {y1, w}
BV(s2):= {f, x1, x2, x, y1, y2}