equal(X, X) -> true;
equal(_, _) -> false.
In Haskell, the following does not compile: equal x x = True
equal _ _ = False
instead, we need to write something like equal x y | x == y = True
| otherwise = False
A subtle difference, but in some cases the structural semantics really do make patterns a lot cleaner (shorter without sacrificing readability).
I think that this style of pattern-matching semantics is a consequence of Erlang's roots in Prolog, which works similarly (and not only checks for structural equivalence but even does unification when necessary).