After about five years programming in Haskell, I think we need a rule: Only put one function in a typeclass.

Why? Because inevitably someone comes along with a data type for which one or the other function of a typeclass is perfectly suited, and yet another function of the same typeclass is not implementable.

Here are some examples of consequences of breaking the rule:

- The Infamous Set Monad, which requires splitting Monad in half. (Monad)
- All of the abstract ways to construct Nothing: fail (Monad), mempty (Monoid), mzero (MonadPlus), empty (Alternative). Not surprisingly, all of these typeclasses are subtly related.
- The natural numbers, which have a minBound, but not a maxBound (Bounded) . . .
- . . . and which support addition and multiplication, but aren’t closed under subtraction and for which the concept of a sign does not exist (Num).
- My own memoizable message type, which would like to implement Applicative, but needs a monadic computation to implement pure. (Applicative)

It’s a little extra typing to write multiple “class . . . where” clauses for each type that needs to implement a large number of type-indexed functions, but it’s quite easy to combine related typeclasses when appropriate, as follows:

class Foo a where foo :: a -> b class Bar a where bar :: a -> b class (Foo a,Bar a) => FooBar a where {this space intentionally left blank}

In conclusion, you should definitely follow this rule if I have convinced you that it is a good idea to follow it.