derive-IG-0.1.1: example/abstract.hs
{-# LANGUAGE TypeOperators, EmptyDataDecls, TypeFamilies, FlexibleContexts, TemplateHaskell #-}
module Main where
import Generics.Instant
import Generics.Instant.Derive
data Expr = Num Int
| Val String
| Plus Expr Expr
| Minus Expr Expr
| Multi Expr Expr
| Div Expr Expr
deriving (Show, Eq)
derive ''Expr
class Normalize a where
normalize :: a -> a
normalize = id
dft_normalize :: (Representable a, Normalize (Rep a)) => a -> a
dft_normalize = to . normalize . from
instance Normalize U
instance Normalize (Var a)
instance (Normalize a, Normalize b) => Normalize (a :+: b) where
normalize (L a) = L (normalize a)
normalize (R b) = R (normalize b)
instance (Normalize a, Normalize b) => Normalize (a :*: b) where
normalize (a :*: b) = normalize a :*: normalize b
instance Normalize a => Normalize (Rec a) where
normalize (Rec a) = Rec (normalize a)
instance Normalize a => Normalize (C con a) where
normalize (C a) = C (normalize a)
{-
-- instance Normalize Int
-- instance Normalize Char
-- instance Normalzie a => Normalize (Maybe a) where normalize = dft_normalize
-- instance Normalzie a => Normalize [a] where normalize = dft_normalize
-- etc, etc...
-}
instance Normalize Expr where
normalize x = case dft_normalize x of
Plus (Num n) (Num m) -> Num (n + m)
Multi (Num n) (Num m) -> Num (n * m)
Minus (Num n) (Num m) -> Num(n - m)
Div (Num n) (Num m) -> Num(n `div` m)
x -> x
-- 2 * (3 + 2 * 5) = 26
tree1 = Multi (Num 2) (Plus (Num 3) (Multi (Num 2) (Num 5)))
-- a * (3 + 2 * 5) = a * 13
tree2 = Multi (Val "a") (Plus (Num 3) (Multi (Num 2) (Num 5)))
tree3 = Multi (Multi (Num 2) (Plus (Num 5) (Num 2))) tree2