Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Deriving for Classes

Just like you can derive instances for data types (example is from homoiconic)

data Foo = F Int Bool 
 deriving Show

maybe it makes sense to do it for certain type classes.

If you define

class Num a where
 (+), (-), (*) :: a -> a -> a
 negate, abs, signum :: a -> a
 fromInteger :: Integer -> a
 
class Num a => Fractional a where
 (/) :: a -> a -> a
 recip :: a -> a
 fromRational :: Rational -> a

the following instances could be define automatically

instance FAlgebra Num where
 data Sig Num a
  = Sig_add a a
  | Sig_mul a a
  | Sig_min a a
  | Sig_neg a
  | Sig_abs a
  | Sig_signum a
  | Sig_fromInteger Integer
  deriving Functor
  
 runSig :: Num a => Sig Num a -> a
 runSig (Sig_add a b)  = a + b
 runSig (Sig_mul a b)  = a * b
 runSig (Sig_min a b)  = a - b
 runSig (Sig_neg a)    = negate a
 runSig (Sig_abs a)    = abs a
 runSig (Sig_signum a) = signum a
 runSig (Sig_fromInteger i) = fromInteger

instance FAlgebra Fractional where
 data Sig Fractional a
  = Sig_div a a
  | Sig_recip a
  | Sig_fromRational Rational
  | Sig_Fractional_Num (Sig Num a)
  deriving Functor
  
 runSig :: Fractional a => Sig Fractional a -> a
 runSig (Sig_div a1 a2)        = a1/a2
 runSig (Sig_recip a)          = recip a
 runSig (Sig_fromRational r)   = fromRational r
 runSig (Sig_Fractional_Num s) = runSig s

for a type class

class Functor (Sig alg) => FAlgebra alg where
 data Sig alg a
 runSig :: alg a => Sig alg a -> a

So my questions are

Are there other (Type -> Constraint) -> Constraint type classes that could be derived.

Could this be automated, like default instances using Generic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment