packages feed

derive-IG-0.1: example/count.hs

{-# LANGUAGE TemplateHaskell, EmptyDataDecls, FlexibleContexts, OverlappingInstances #-}
{-# LANGUAGE FlexibleInstances ,TypeSynonymInstances, TypeFamilies, TypeOperators #-}
module Main where
import Generics.Instant
import Language.Haskell.TH
import Generics.Instant.Derive

data Expr = N Int
          | V String
          | P Expr Expr
            deriving (Show, Eq, Ord)

derive ''Expr
deriveWith ''(,,) [Just "Triple_Con"]
deriveWith ''()   [Just "Unit_Unit"]


class Count a where
    count :: a -> Int
    count _ = 1

instance Count Int
instance Count Char
instance Count Bool
instance Count String

instance Count U
instance Count (C con U)
instance Count a => Count (Var a) where
    count (Var a) = count a
instance (Count a, Count b) => Count (a :*: b) where
    count (a :*: b) = count a + count b
instance (Count a) => Count (Rec a) where
    count (Rec a) = count a
instance Count a => Count (C con a) where
    count (C a) = 1 + count a
instance (Count a, Count b) => Count (a :+: b) where
    count (L a) = count a
    count (R b) = count b

dft_count :: (Representable a, Count (Rep a)) => a -> Int
dft_count = count . from

instance Count () where count = dft_count
instance Count a => Count (Maybe a) where count = dft_count
instance Count a => Count [a] where count = dft_count
instance (Count a, Count b) => Count (a, b) where count = dft_count
instance (Count a, Count b, Count c) => Count (a, b, c) where count = dft_count
instance Count Expr where count = dft_count