Different behaviours of Cases
Different behaviours of Cases
Why does Cases output an element only in the first of the following lines?
Cases
Cases[1, a -> 2 b, HoldPattern[a -> 2 b]]
(*a->2b*)
Cases[1, a -> 1/2 b, HoldPattern[a -> 1/2 b]]
(**)
Cases[1, a -> π b, HoldPattern[a -> π b]]
(**)
Cases[1, a -> c b, HoldPattern[a -> c b]]
(**)
FullForm@HoldPattern[a -> 1/2 b]
FullForm@1, a -> 1/2 b
Huh, that was a nasty one!
– Henrik Schumacher
Aug 23 at 8:58
Use
PatternSequence in place of HoldPattern– kglr
Aug 23 at 8:59
PatternSequence
HoldPattern
@kglr I think that is worth an answer and an explanation. (I'm personally interested.)
– Henrik Schumacher
Aug 23 at 9:01
See also this: mathematica.stackexchange.com/a/73020/5478
– Kuba♦
Aug 23 at 9:12
3 Answers
3
As an alternative to HoldPattern[Evaluate[...] you can use PatternSequence which evaluates its argument:
HoldPattern[Evaluate[...]
PatternSequence
Cases[1, a -> 2 b, PatternSequence[a -> 2 b]],
Cases[1, a -> 1/2 b, PatternSequence[a -> 1/2 b]],
Cases[1, a -> π b, PatternSequence[a -> π b]],
Cases[1, a -> c b, PatternSequence[a -> c b]]
a -> 2 b, a -> b/2, a -> b π, a -> b c
Alternatively, give the pattern a name:
Cases[1, a -> 2 b, p : (a -> 2 b)],
Cases[1, a -> 1/2 b, p : (a -> 1/2 b)],
Cases[1, a -> π b, p : (a -> π b)],
Cases[1, a -> c b, p : (a -> c b)]
a -> 2 b, a -> b/2, a -> b π, a -> b c
Thanks to Kuba's comment now I see:HoldPattern prevents the evaluation of its argument, so Cases don't match the element in the list a->b/2 that is
HoldPattern
Cases
a->b/2
Times[Rational[1, 2], b]
with the unevaluated pattern
Times[b, Power[2, -1]]
Evaluate the argument of HoldPattern solves the problem:
HoldPattern
Cases[1, a -> b/2, HoldPattern[Evaluate[a -> b/2]]]
(*a -> b/2*)
Thanks Kuba!
You can define
myHoldPattern[x___] = HoldPattern[x]; and use in place of HoldPattern to reduce clutter. Since myHoldPattern does not hold its argument, unlike the bona fide HoldPattern, the evaluation will have happened by the time x is wrapped into HoldPattern for matching.– kkm
Aug 23 at 9:19
myHoldPattern[x___] = HoldPattern[x];
HoldPattern
myHoldPattern
HoldPattern
x
HoldPattern
Here is another way by using Verbatim. Maybe it feels a bit less hacky.
Verbatim
Cases[1, a -> 2 b, Verbatim[a -> 2 b]],
Cases[1, a -> 1/2 b, Verbatim[a -> 1/2 b]],
Cases[1, a -> π b, Verbatim[a -> π b]],
Cases[1, a -> c b, Verbatim[a -> c b]]
a -> 2 b, a -> b/2, a -> b π, a -> b c
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
compare
FullForm@HoldPattern[a -> 1/2 b]andFullForm@1, a -> 1/2 b, the rest is about reordering.– Kuba♦
Aug 23 at 8:38