The document says:

OneIdentity is an attribute that can be assigned to a symbol f to indicate that f[x], f[f[x]], etc. are all equivalent to x for the purpose of pattern matching.

Consider the expressions below:

In[1]:= SetAttributes[f, OneIdentity]
In[2]:= Nest[f, x, 10]
Out[2]= f[f[f[f[f[f[f[f[f[f[x]]]]]]]]]]


We cannot get f[x] as the document says.

In[1]:= MatchQ[x, Times[n_. , x_]]
Out[1]= True


Also, the example in the document seems a little confusing. What does the pattern Times[n_.,x_] mean?

I'm quite confused about it. Please explains this.

• It treats the expression as equivalent to x for the purpose of pattern matching. It doesn't evaluate to x. Commented Aug 20, 2016 at 5:11

What the documentation means is that for a symbol f with attribute OneIdentity, pattern forms like f[_.,x], f[_.,f[_.,x]], etc. (Note the Possible Issues section!) will not only match expression like f[4,a] but also an expression without a Head f.

Take the CirclePlus, which has no built-in meaning or any attribute, as an example.

Clear[CirclePlus]
ClearAttributes[CirclePlus, Attributes@CirclePlus];
DefaultValues[CirclePlus] = {};
Attributes[CirclePlus]

{}


This will work as expected:

k⊕y /. a_⊕x_ :> {a, x}
k⊕y /. a_.⊕x_ :> {a, x}

{k, y}
{k, y}


But this won't work because a_.⊕x_ or (a_:1)⊕x_ won't match y:

y /. a_.⊕x_ :> {a, x}
y /. (a_: 1)⊕x_ :> {a, x}

y
y


Instead of introducing a special rule like x_:>{1,x}, we can add the OneIdentity to CirclePlus:

SetAttributes[CirclePlus, OneIdentity]


Now this works as well:

y /. (a_: 1)⊕x_ /; (Echo[a]; True) :> {a, x}

1
{1, y}


This still won't work

y /. a_.⊕x_ :> {a, x}


until CirclePlus gets DefaultValues:

Default[CirclePlus] := RandomReal[];


Now a_.⊕x_ will match y:

y /. a_.⊕x_ /; (Echo[a]; True) :> {a, x}

0.217426
{0.217426, y}


And nested CirclePlus will also match y:

y /. a_.⊕(b_.⊕x_) /; (Echo[{a, b}]; True) :> {a, b, x}

{0.934169, 0.157904}
{0.934169, 0.157904, y}

y /. a_.⊕(x_⊕b_.) /; (Echo[{a, b}]; True) :> {a, b, x}

{0.319821, 0.490549}
{0.319821, 0.490549, y}


or match 4⊕y:

4⊕y /. a_.⊕(x_⊕b_.) /; (Echo[{a, b}]; True) :> {a, b, x}

{4, 0.861579}
{4, 0.861579, y}

• @ShutaoTang I'm a bit of busy this year. (But I still visit the site regularly!) Commented Aug 20, 2016 at 16:00
• @Silvia 膜巨神……话说还有那些中国人在这里？感觉完全认不全
– Wjx
Commented Aug 22, 2016 at 3:17