Why does Haskell stop short of inferring the datatype's typeclasses in the function signatures?
haskell, interface, type-constraints, typeclass, types
Solution
Perhaps `Map k v` wasn't the best example to illustrate the point. Given the definition of `Map`, even though there are some functions that won't need the `(Ord k)` constraint, there is no possible way to construct a `Map` without it.
One often finds that a type is quite usable with the sub-set of functions that work on without some particular constraint, even when you envisioned the constraint as an obvious aspect of your original design. In such cases, having left the constraint off the type declaration leaves it more flexible.
For example, `Data.List` contains plenty of functions that require `(Eq a)`, but of course lists are perfectly useful without that constraint.
Problem
Firstly, this question isn't 100% specific to Haskell, feel free to comment on the general design of typeclasses, interfaces and types. I'm reading LYAH - creating types and typeclasses The following is the passage that I'm looking for more information on: ``` Data (Ord k) => Map k v = ... ``` However, it's a very strong convention in Haskell to never add typeclass constraints in data declarations. Why? Well, because we don't benefit a lot, but we end up writing more class constraints, even when we don't need them. If we put or don't put the Ord k constraint in the data declaration for Map k v, we're going to have to put the constraint into functions that assume the keys in a map can be ordered. But if we don't put the constraint in the data declaration, we don't have to put (Ord k) => in the type declarations of functions that don't care whether the keys can be ordered or not. An example of such a function is toList, that just takes a mapping and converts it to an associative list. Its type signature is toList :: Map k a -> [(k, a)]. If Map k v had a type constraint in its data declaration, the type for toList would have to be toList :: (Ord k) => Map k a -> [(k, a)], even though the function doesn't do any comparing of keys by order. This at first, seems logical -- but isn't there an upside to having the typeclass attached to the type? If the typeclass is the behavior of the type, then why should the behavior be defined by the use of the type (through functions), and not the type itself? I assume there is some meta-programming that could make use of it, and it is certainly nice and descriptive code-documentation. Conversely, would this be a good idea in other languages? Would it be ideal to specify the interface the object should conform to on the method, such that if the method isn't used by the caller the object doesn't have to conform to the interface? Moreover, why can Haskell not infer that a function using type `Foo`, has to pull in the typeclass constraints identified in type `Foo`'s declaration? Is there a pragma to enable this? The first time I read it, it conjured a "that's a hack (or workaround) response". On second read with some thought, it sounded clever. On third read, drawing a compairison to the OO world, it sounded like a hack again. So here I am.