I'd like to hear some pros and cons about where it's best to put Haskell typeclass instances. I identify 2 possible cases and can not decide for myself which one is best:
- Put the instances together with the typeclass definition;
- Put them together with the types that implement it.
For the sake of this example, lets say we have a ToJSON typeclass. It, as the name says, has a function that converts a to a JSON:
class ToJSON a where
toJSON :: a -> JSON
Pros for the first case. Putting all ToJSON instances in the actual typeclass file results in a separation of concerns. For example, the Color type should only care about it's constructors and functions that manipulate the color, not about JSON serialization. Let the JSON type worry about that.
Pros for the second case. Assuming we export only Color type and not it's constructors, putting the ToJSON instance in Color.hs allows the use of patters matching. Also, having all of the instances near the type shows the developer all things the type can do.
Keep in mind that this is a personal preference list based on experience. Feel free to add to or disagree about it.