Summary: Generic programming should be based on representational equality. We can obtain this by reformulating “data” in terms of “newtype”: manually or (tentatively) with compiler support
Background
In modern Haskell we often seek to derive instances, meaning to have the compiler generate them for us, as opposed to writing them by hand. Deriving instances is not just more convenient but also safer and encourages deduplication and code reuse.
Currently GHC provides three different strategies for deriving instances: stock, anyclass and newtype. The stock strategy is the original approach to deriving in Haskell and is “magic”: it is hardcoded in the compiler and only works on a predefined set of classes, such as Eq, Show, Typeable, Functor and so on.
The anyclass strategy is just syntactic sugar for writing empty instance declarations and we will not be focusing on it here. The most...