关于嵌套Unevaluated的问题

Ale*_*kov 6 wolfram-mathematica

试图模拟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]
Run Code Online (Sandbox Code Playgroud)

可以看到,只有偶数个嵌套Unevaluated包装器被完全删除.为什么?

Mic*_*lat 9

关键是,Unevaluated在表达式进行模式匹配之前,有效地删除了一层.来自文档:

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]]]]评估as 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!


And*_*lan 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]]}
Run Code Online (Sandbox Code Playgroud)
  1. 由于的定义特殊属性Unevaluated的语言结构,f[Unevaluated[1 + 1]]评估就像f[1 + 1]除了1 + 1留下未评估.
  2. f[1 + 1]与您给出的定义不符f.
  3. 因此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]}
Run Code Online (Sandbox Code Playgroud)
  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].