f :: a -> a
can only be satisfied by the function
identity because there are no constraints on the type (
a).
identity is the lowest common denominator function that can transform an object of any type to another object of the same type.
If you added a constraint on a, for instance:
f :: Num a => a -> a
Now
f can be almost any function which can transform a numeric type back to the same numeric type. [0] describes
class Num. So
f, with this constraint, can now be
negate,
abs,
signum, or something which combined the first parameter with itself using one of the operators, and so on.
By removing constraints on the type itself, Haskell necessarily restricts the set of operations that can be performed.
[0] https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelu...