This is probably a very basic question, but ...
A function that\'s defined as, say
foo :: a -> Integer
denotes a function from <
Haskell enjoys an implementation strategy known as "type erasure": types have no computational significance, so the code that you emit doesn't need to track them. This is a significant boon for performance.
The price you pay for this performance benefit is that types have no computational significance: a function can't change its behavior based on the type of an argument it is passed. If you were to allow something like
f () = "foo"
f [] = "bar"
then that property would not be true: the behavior of f would, indeed, depend on the type of its first argument.
There are certainly languages that allow this kind of thing, especially in dependently typed languages where types generally can't be erased anyway.