{-# LANGUAGE KindSignatures             #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE RankNTypes                 #-}
{-# LANGUAGE TypeOperators              #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE ScopedTypeVariables        #-}

module Generics.MultiRec.CountIs where

import Generics.MultiRec

--------------------------------------------------------------------------------
-- Count I's (for showing)
--------------------------------------------------------------------------------

class CountIs (f :: (* -> *) -> * -> *) where
  countIs :: f r ix -> Int

instance CountIs (I ix)    where countIs _ = 1
instance CountIs (t :.: f) where countIs _ = 1
instance CountIs (K a)     where countIs _ = 0
instance CountIs U         where countIs _ = 0

instance (CountIs f) => CountIs (C c f)    where
  countIs (_ :: C c f r ix)      = countIs (undefined :: f r ix)
instance (CountIs f) => CountIs (f :>: ix) where
  countIs (_ :: (f :>: ix) r xi) = countIs (undefined :: f r ix)

instance (CountIs f, CountIs g) => CountIs (f :+: g) where
  countIs (L x) = countIs x
  countIs (R x) = countIs x

instance (CountIs f, CountIs g) => CountIs (f :*: g) where
  countIs (_ :: (f :*: g) r ix) = countIs (undefined :: f r ix)
                                + countIs (undefined :: g r ix)