To demonstrate @David's answer in a small example, imagine you're implementing another incarnation of a balanced binary tree. Of course keys must be Ord
ered, so you add a constraint to the type declaration:
data Ord k => Tree k v = Tip | Bin k v (Tree k v) (Tree k v)
Now this constraint infects every other signature everywhere you're using this type, even when you don't really need to order keys. It wouldn't probably be a bad thing (after all, you'll need to order them at least somewhere – otherwise, you aren't really using this Tree
) and it definitely doesn't break the code, but still makes it less readable, adds noise and distracts from important things.
empty :: Ord k => Tree k v
singleton :: Ord k => k -> v -> Tree k v
find :: Ord k => (v -> Bool) -> Tree k v -> Maybe v
instance Ord k => Functor (Tree k)
In all of these signatures the constraint could be omitted without any problems.