Mathematica knows two types of expressions: compound expressions and atomic expressions.
For example, in
x are atomic. They are used to construct a compound expression
General expression manipulation, such as extracting or changing parts or replacing parts does not work on atomic expressions. That's because they're "atomic", i.e. indivisible, they do not have parts.
This is why you can't replace the head of an
Association: it does not have a head, as it does not have any parts.
AtomQ can be used to test if an expression is atomic.
To be more precise, the situation is a bit more complicated in practice. Some atomic objects do have a full form which looks like a compound expression. E.g.
Complex[1, 2] looks like it has head
Complex, and parts
2. When you enter this expression, it is indeed a compound expression made of these three parts. However, it will immediately evaluate to a truly atomic expression, which means that
Complex[1, 2] /. Complex -> complex won't work.
To make the situation even more complicated, some atomic objects do have some support for manipulating and extracting "parts", e.g. you can index a
SparseArray. Consider this as a special support. Each type of atomic object is different and each of them support different kinds of manipulations.
The general guideline is to consider atomic objects indivisible.