Search code examples
haskelltypeclasstype-systems

Lifting class instance in Haskell


Is there a way to "lift" a class instance in Haskell easily?

I've been frequently needing to create, e.g., Num instances for some classes that are just "lifting" the Num structure through the type constructor like this:

data SomeType a = SomeCons a

instance (Num a)=>Num SomeCons a where
    (SomeCons x) + (SomeCons y) = SomeCons (x+y)
    negate (SomeCons x) = SomeCons (negate x)
    -- similarly for other functions.

Is there a way to avoid this boilerplate and "lift" this Num structure automatically? I usually have to do this with Show and other classes also when I was trying to learn existencials and the compiler wouldn't let me use deriving(Show).


Solution

  • The generalized newtype deriving extension is what you want here:

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    
    module Main where
    
    newtype SomeType a = SomeCons a deriving (Num, Show, Eq)
    
    main = do
      let a = SomeCons 2
          b = SomeCons 3
      print $ a + b
    

    Output:

    *Main> main
    SomeCons 5