The whole point of parametric polymorphism (as opposed to eg ad-hoc polymorphism) is that just from reading the type of a function you get a guarantee about the limits of its behaviour.
If you functions routinely violate those limits as a matter of course, those guarantees are useless.
I'm all for abusing notation and terminology a bit when it makes sense in practice, but loosening our definitions too much risks making them useless, too.
In practice in Haskell, I often only need a helper function for eg integers, but when the implementation allows, I will give the function the most parametric-polymorphic type that fits, because that makes the readers job easier:
Just like an invocation of `filter` is easier to read than a for-loop, because `filter` is strictly less powerful than the loop.
(In addition, the more general type serves to give the compiler a hint, so it can yell at me in case I accidentally do an operation on the integer that I didn't mean to.)
If you functions routinely violate those limits as a matter of course, those guarantees are useless.
I'm all for abusing notation and terminology a bit when it makes sense in practice, but loosening our definitions too much risks making them useless, too.
In practice in Haskell, I often only need a helper function for eg integers, but when the implementation allows, I will give the function the most parametric-polymorphic type that fits, because that makes the readers job easier:
Just like an invocation of `filter` is easier to read than a for-loop, because `filter` is strictly less powerful than the loop.
(In addition, the more general type serves to give the compiler a hint, so it can yell at me in case I accidentally do an operation on the integer that I didn't mean to.)