关于嵌套Unevaluated的问题

时间:2011-06-08 05:13:47

标签: wolfram-mathematica

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包装器被完全删除。为什么呢?

2 个答案:

答案 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]]}
  1. 由于Unevaluated语言构造的定义特殊属性,f[Unevaluated[1 + 1]]的评估方式与f[1 + 1]类似,但1 + 1未被评估。
  2. f[1 + 1]与您为f提供的定义不符。
  3. 因此f[Unevaluated[1 + 1]]仍未评估。
  4. 鉴于:

    In[3]:= f[Unevaluated@Unevaluated[1 + 1]] // Trace
    Out[3]= {f[Unevaluated[1+1]],f[1+1],{1+1,2},f[2]}
    
    1. 由于Unevaluated语言构造的定义特殊属性,f[Unevaluated@Unevaluated[1 + 1]]的评估方式与f[Unevaluated[1 + 1]]类似,但Unevaluated[1 + 1]未被评估。
    2. f[Unevaluated[1 + 1]]符合您为f提供的定义,并评估为f[1 + 1]
    3. 因此f[Unevaluated@Unevaluated[1 + 1]]评估为f[2]