jakubdaniel
jakubdaniel

Reputation: 2223

Automatic haskell deriving declaration that lifts

Is there a way to have the compiler derive the functionality that I would write manually as:

instance Class c => Class (Trans c) where
    foo1 = lift foo1
    foo2 = lift foo2
    ...
    foo999 = lift foo999
    bar1 = \a b c -> lift $ bar1 a b c
    ...
    baz1 = lift . baz1
    ...

i.e. when a type of class Class is being wrapped in Trans, is it possible to get a free instance of Class for Trans automatically without having to do the heavy lifting :)?

Upvotes: 1

Views: 109

Answers (1)

bergey
bergey

Reputation: 3081

If lift is itself a type class function, you can write a general definition for all instances of the type class. Something like:

instance (Class c, Trans t) => Class (t c)

Be careful that this doesn't overlap with any other instances, and is what you want for all these types.

As a more complete example, this code works, even though it's results are sometimes surprising.

{-# LANGUAGE FlexibleInstances #-}

module Inst where

import Control.Applicative (liftA2)

instance (Applicative f, Num n) => Num (f n) where
  (+) = liftA2 (+)
  (*) = liftA2 (*)
  abs = fmap abs
  signum = fmap signum
  fromInteger = pure . fromInteger
  negate = fmap negate

Upvotes: 1

Related Questions