modular
modular

Reputation: 1099

How to organize Haskell modules with instances: stick to data type vs type class?

The general question is which module structure is more convenient when adding instances for existing objects? Which pros and cons there are?

Let's say I want to add NFData instance for Seq type. I can place it in:

It's the case when I don't own neither the type class nor the data type. The other common situation is when I own a type type class and want to add instances for data type(s) from some "heavy" package from Hackage, like OpenGL. Let's say the type class I designed is very light and has no direct relation to OpenGL. I don't want my type class depend on "heavy" package, so I want to place OpenGL instances in a separate module (it's my intuitive feeling, if you have other opinion, let's discuss it). So, what this module should be:

What is more flexible solution? At some point OpenGL can be replaced with other library, or MyClass can be replaced too. Are there any subtle nuances?

Also, which scheme is better if choose MyClass.Instances variant:

Upvotes: 13

Views: 1996

Answers (1)

hammar
hammar

Reputation: 139890

The usual process of deciding where to put an instance goes something like this:

  1. If you're making a new data type and want an instance for an existing class:

    Put the instance in the same module as the data type.

  2. If you're making a new type class and want to make instances for existing types.

    Put the instances in the same module as the type class.

  3. Both the type class and the data type already exist (your case).

    If the instance is sufficiently general, I'd contact the author of either the type class or the data type and try to convince them to add the instance in their package.

    Otherwise, create a newtype wrapper and write an instance for that.

    Only as a last resort consider making an orphan instance.

Upvotes: 13

Related Questions