嵌套问题无法评估
当trying模拟评估行为RuleDelayed
我遇到了嵌套Unevaluated
的意外行为。试想一下:嵌套问题无法评估
In[1]:= f[Verbatim[Unevaluated][expr_]] := f[expr]
f[Unevaluated[1 + 1]]
f[[email protected][1 + 1]]
f[[email protected]@Unevaluated[1 + 1]]
f[[email protected]@[email protected][1 + 1]]
Out[2]= f[Unevaluated[1 + 1]]
Out[3]= f[2]
Out[4]= f[Unevaluated[1 + 1]]
Out[5]= f[2]
人们可以看到,只有偶数嵌套Unevaluated
包装的完全去除。为什么?
使用跟踪明白为什么:
In[1]:= f[Verbatim[Unevaluated][expr_]]:=f[expr]
In[2]:= f[Unevaluated[1+1]]//Trace
Out[2]= {f[1+1],f[Unevaluated[1+1]]}
- 由于
Unevaluated
语言结构的定义特殊属性,f[Unevaluated[1 + 1]]
评估类似,只是在1 + 1
f[1 + 1]
留下未评估。 -
f[1 + 1]
与您给出的f
的定义不符。 - 因此
f[Unevaluated[1 + 1]]
仍未评估。
鉴于:
In[3]:= f[[email protected][1 + 1]] // Trace
Out[3]= {f[Unevaluated[1+1]],f[1+1],{1+1,2},f[2]}
- 由于
Unevaluated
语言结构的定义特殊属性,f[[email protected][1 + 1]]
评估类似,只是在Unevaluated[1 + 1]
f[Unevaluated[1 + 1]]
留下未评估。 -
f[Unevaluated[1 + 1]]
与您给出的f
的定义相符,并且评估为f[1 + 1]
。因此f[[email protected][1 + 1]]
评估为f[2]
。
关键是,在表达式模式匹配之前,有效地删除了一层Unevaluated
。从docs:
f[Unevaluated[expr]]
有效地工作 通过临时设置属性,这样 是f
持有它的参数未计算, 然后评估f[expr]
。
因此,在第一种情况下,f[Unevaluated[1 + 1]]
评价为f[1 + 1]
,但图案匹配即使f
缺乏Hold*
属性时残留未计算,和因为没有匹配f[1 + 1]
,所述原始表达(预图案 - 匹配)返回未评估。
在第二种情况下,f[Unevaluated[Unevaluated[1 + 1]]]
评估为f[Unevaluated[1 + 1]]
在模式匹配器,其确实为f
匹配的模式,然后f[1 + 1]
递归评价,因此你得到f[2]
。
在第三种情况下,f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]
评估为f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]
,匹配,并递归评估为f[Unevaluated[1 + 1]]
,我们又回到第一种情况。
在第四种情况下,f[Unevaluated[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]]
上f[Unevaluated[Unevaluated[Unevaluated[1 + 1]]]]
比赛,递归地评估f[Unevaluated[Unevaluated[1 + 1]]]
,我们又回到了第二种情况。
HTH!
哇,我真的打你几秒钟的答案=) – 2011-06-08 06:10:02
是啊!一个小时以前的问题很巧合。我总体上更喜欢你的答案。 – 2011-06-08 06:17:09
非常明确的解释,谢谢!两种答案都很好,并且相互补充,但是你对评估者采取的一系列决定形式的解释更加简单和易于记忆。所以我接受你的答案。 – 2011-06-08 07:35:13