5
$\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$
  • $\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 May 29 '15 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 May 29 '15 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 May 29 '15 at 20:45
  • 5
    $\begingroup$ Or even more readable pattern = {(_foo|_bar)..} $\endgroup$ – N.J.Evans May 29 '15 at 20:55
  • $\begingroup$ Thanks! I guess it can not be short than this. Could you turn it to answer? $\endgroup$ – Johu May 29 '15 at 21:02
11
$\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, privacy policy and cookie policy

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