Type classes are for reusability

From HaskellWiki
Jump to navigation Jump to search

I see a certain overuse of typeclasses in Haskell libraries. Type classes are not intended for massive re-use of some short identifier like fmap or in order to access some syntactic sugar (e.g. do notation or number literals). Instead type classes exist for writing reusable code. Functions written using the Num type class like polynomial multiplication work (almost) equally for Int, Integer, Rational, Float, Double and custom number types. Functions like mapM and replicateM that only need a Monad constraint can be used for all monads including any combination of monad transformers.

Thus, think twice:

  • Do you really need a Num instance for a network port, just in order to be able to write 80 for a port number? How would sensible definitions of (*) would look like? (Actually, it was not necessary to bundle the number literal feature expressed by the fromInteger method with the (+) and (*) operations, and indeed Numeric Prelude chooses a different set of operations. But it is generally accepted that number literals are reserved for objects that allow some sort of arithmetics.) Isn't port 80 even more comprehensible?

  • Do you really need a Functor instance for the pair type? What distinguishes the second member from the first member? Is the generic pair type the right choice, or should it better be a custom type?

  • Do you really need a Monad instance for writing something to a stream? Or did you define the instance only for the do notation? Please, give the monoid a try!

  • See also