原因是你必须逃避HoldPattern
,也许与Verbatim:
In[11]:= Cases[dvs,
Verbatim[RuleDelayed][
Verbatim[HoldPattern][HoldPattern[f[_Integer]]], _]]
Out[11]= {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 2}
只有少数几个头需要这样做,并且HoldPattern
是其中之一,正是因为它通常对模式匹配器来说是“不可见的”。为您temporary
或其他负责人,这没有必要。顺便注意一下,该模式f[_Integer]
被包裹在HoldPattern
- 这次HoldPattern
用于其直接目的 - 保护模式免受评估。注意RuleDelayed
也被包裹在Verbatim
- 这实际上是另一个常见的情况Verbatim
- 这是需要的,因为Cases
有一个涉及规则的语法,我们不希望Cases
在这里使用这个解释。所以,在我看来,这是一个很好的例子来说明两者HoldPattern
and Verbatim
。
另请注意,可以完全实现目标HoldPattern
,像这样:
In[14]:= Cases[dvs,HoldPattern[HoldPattern[HoldPattern][f[_Integer]]:>_]]
Out[14]= {HoldPattern[f[1]]:>1,HoldPattern[f[2]]:>2}
然而,使用HoldPattern
用于转义目的(代替Verbatim
)在国际海事组织(IMO)概念上是错误的。
EDIT
澄清一下情况Cases
,这是一个简单的示例,我们使用以下语法Cases
涉及到变换规则。此扩展语法指示Cases
不仅找到并收集匹配的棋子,而且在找到它们后立即根据规则对其进行转换,因此结果列表包含转换后的棋子。
In[29]:= ClearAll[a, b, c, d, e, f];
Cases[{a, b, c, d, e, f}, s_Symbol :> s^2]
Out[30]= {a^2, b^2, c^2, d^2, e^2, f^2}
但是如果我们需要找到本身就是规则的元素怎么办?如果我们尝试这样做:
In[33]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_]
Out[33]= {}
从那时起它就不起作用了Cases
将第二个参数中的规则解释为使用扩展语法的指令,找到一个符号并将其替换为_
。由于默认情况下它在级别 1 上搜索,而符号在此处位于级别 2 上,因此它什么也没找到。观察:
In[34]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_,{2}]
Out[34]= {_,_,_,_,_,_}
无论如何,这都不是我们想要的。因此,我们必须强制Cases
将第二个参数视为普通模式(简单语法,而不是扩展语法)。有几种方法可以做到这一点,但它们都“逃避”RuleDelayed
(or Rule
) 某种程度上来说:
In[37]:= Cases[{a:>b,c:>d,e:>f},(s_Symbol:>_):>s]
Out[37]= {a,c,e}
In[38]:= Cases[{a:>b,c:>d,e:>f},Verbatim[RuleDelayed][s_Symbol,_]:>s]
Out[38]= {a,c,e}
In[39]:= Cases[{a:>b,c:>d,e:>f},(Rule|RuleDelayed)[s_Symbol,_]:>s]
Out[39]= {a,c,e}
在所有情况下,我们要么避免使用扩展语法Cases
(最后两个例子),或者设法利用它来发挥我们的优势(第一种情况)。