6
$\begingroup$

I have a function, which I want to accept only a list of kind of elements belonging to a group. The task comes down to finding an elegant pattern suitable for easy to read function prototype.

As an example I have a pattern, which works:

pattern = {__?(Head[#] === foo || Head[#] === bar &)}

but I am sure, that it can be in a more elegant way.

Here are some cases were I expect the pattern to match the parameter:

MatchQ[{foo[a1], bar[b1, b2], foo[c1], bar[b1, b2]}, pattern]
MatchQ[{foo[a1]}, pattern]

And here I expect to get false:

MatchQ[{foo[a1], bar[b1, b2], cha[c1, c2]}, pattern]
MatchQ[{}, pattern]
MatchQ[{foo}, pattern]
MatchQ[{1}, pattern]
MatchQ[foo, pattern]

Weakly related to "Pattern matching to head with holdfirst".

$\endgroup$
5
  • $\begingroup$ I don't know if I'd call it more elegant, but you can use the x_Head notation and do pattern = {__?(# /. y_foo | y_bar -> True &)}. Is there any particular criterion you're interested in? $\endgroup$
    – N.J.Evans
    Commented May 29, 2015 at 20:01
  • $\begingroup$ It is an alternative but I would not call it more elegant. Imagen a function prototype of the form f[x : {__?(# /. y_foo | y_bar -> True &)}] := test[x], Hiding the pattern in some function f[x : {__?patternTest}] would not be much better, as then one needs to look up pattern to see the format. $\endgroup$
    – Johu
    Commented May 29, 2015 at 20:10
  • 2
    $\begingroup$ So are you looking for a better way to write the pattern? You could also do 'pattern = {(foo|bar)[__]..}` which is more readable to me. $\endgroup$
    – N.J.Evans
    Commented May 29, 2015 at 20:45
  • 5
    $\begingroup$ Or even more readable pattern = {(_foo|_bar)..} $\endgroup$
    – N.J.Evans
    Commented May 29, 2015 at 20:55
  • $\begingroup$ Thanks! I guess it can not be short than this. Could you turn it to answer? $\endgroup$
    – Johu
    Commented May 29, 2015 at 21:02

1 Answer 1

13
$\begingroup$

You can use the syntax for matching a head _Head, along with the alternative | symbol, and repeated .. to do pattern = {(_foo|_bar)..}. Which should match any list containing only expressions with the heads foo, and bar in any order.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.