{{ message }}

Instantly share code, notes, and snippets.

# Icelandjack/DerivingClasses.md

Last active Jan 30, 2017
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_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