Reputation: 2223
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
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