I researched Flat
a little bit about a year ago when I wrote this answer. It isn't as clear as can be. It needs updating, and perhaps I'll do that soon. In any case, taking the relevant paragraph:
When the pattern matcher finds itself comparing arguments of an expression whose head (let's call it head
) has attribute Flat
, it behaves differently: patterns of length one (_
, r_
, Condition
s, PatternTest
s) trigger the pattern matcher to automatically wrap a head
around the respective arguments of the expression so both the expression and the pattern have the same number of arguments (could also be a single argument, but it never leaves it as is. Don't know the purpose). In cases where more than one option is possible due to having __s
as arguments, it just starts trying one way and if it doesn't match, tries the next).
In[47]:= ClearAll[f]; SetAttributes[f, {Flat, HoldAllComplete}];
Cases[Hold@f[1], Hold@f[i_] :> Hold[i], {0}]
Cases[Hold@f[1, 2, 3, 4], Hold@f[1, i_, 4] :> Hold[i], {0}]
Cases[Hold@f[1, 2, 3, 4], Hold@f[i_, __] :> Hold[i], {0}]
Cases[Hold@f[1, 2, 3, 4],
Hold@f[i_, j__ /; Length[{j}] === 2] :> Hold[i], {0}]
Out[48]= {Hold[f[1]]}
Out[49]= {Hold[f[2, 3]]}
Out[50]= {Hold[f[1]]}
Out[51]= {Hold[f[1, 2]]}
This case
See this
MatchQ[M[F1[a]], M[_F1]]
MatchQ[M[F1[a]], M[_M]]
(* False *)
(* True *)
The fact that your blank _F1
only matches with head F1
doesn't change the fact that it's a blank, so it actually tries to match M[M[F1[a]]]
to M[_F1]
and fails. You can use M[F1[___]]
to prevent this (or set OneIdentity
if appropriate)
OneIdentity
attribute as perFlat
documentation. $\endgroup$OneIdentity
is wrong. Head should not disappear. $\endgroup$