What’s the “|” for in a Haskell class definition?

The vertical bar is a syntactic separator with no meaning itself, used to introduce functional dependencies on a multi-parameter type class, so technically | means nothing whatsoever. Presumably | was chosen as a visual analogy to the same symbol’s use for pattern guards on functions.

As far as the functional dependencies themselves go, just read x -> y as “type parameter x uniquely determines type parameter y“, meaning that knowing x alone is sufficient to find the correct instance. There are further complications, especially with other GHC extensions enabled, but most of the time you don’t need to worry about them.

In contrast, without functional dependencies, selecting an instance of a multi-parameter type class requires that all type parameters be known. A typical example has one parameter being a container type and a second being the type of the contained elements; functions such as “concatenate” or “isEmpty” need not mention the element type, only the container type, and thus would be ambiguous.

Also, if you’re writing your own type classes, consider instead using type families, which are a new approach that may eventually replace functional dependencies. Roughly speaking, type families let you write overloaded type definitions inside an instance, not just overloaded functions.

Leave a Comment