当trying模拟RuleDelayed
的评估行为时,我遇到了嵌套Unevaluated
的意外行为。考虑:
In[1]:= f[Verbatim[Unevaluated][expr_]] := f[expr]
f[Unevaluated[1 + 1]]
f[Unevaluated@Unevaluated[1 + 1]]
f[Unevaluated@Unevaluated@Unevaluated[1 + 1]]
f[Unevaluated@Unevaluated@Unevaluated@Unevaluated[1 + 1]]
Out[2]= f[Unevaluated[1 + 1]]
Out[3]= f[2]
Out[4]= f[Unevaluated[1 + 1]]
Out[5]= f[2]
可以看到,只有偶数个嵌套Unevaluated
包装器被完全删除。为什么呢?
答案 0 :(得分:9)
关键是,在表达式进行模式匹配之前,有效地删除了一层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
的模式,然后{{1递归评估,因此得到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]]]]
,我们又回到了第二种情况。
HTH!
答案 1 :(得分:8)
使用Trace查看原因:
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]]
的评估方式与f[1 + 1]
类似,但1 + 1
未被评估。f[1 + 1]
与您为f
提供的定义不符。f[Unevaluated[1 + 1]]
仍未评估。鉴于:
In[3]:= f[Unevaluated@Unevaluated[1 + 1]] // Trace
Out[3]= {f[Unevaluated[1+1]],f[1+1],{1+1,2},f[2]}
Unevaluated
语言构造的定义特殊属性,f[Unevaluated@Unevaluated[1 + 1]]
的评估方式与f[Unevaluated[1 + 1]]
类似,但Unevaluated[1 + 1]
未被评估。f[Unevaluated[1 + 1]]
符合您为f
提供的定义,并评估为f[1 + 1]
。f[Unevaluated@Unevaluated[1 + 1]]
评估为f[2]
。