module Data.Singletons.Promote.Bounded where
import Language.Haskell.TH.Desugar
import Data.Singletons.Names
import Data.Singletons.Util
import Control.Monad
mkBoundedTypeInstance :: DsMonad q => DKind -> [DCon] -> q [DDec]
mkBoundedTypeInstance kind@(DConK name _) cons = do
when (null cons
|| (any (\(DCon _ _ _ f) -> not . null . tysOfConFields $ f) cons
&& (not . null . tail $ cons))) $
fail ("Can't derive promoted Bounded instance for " ++ show name
++ " datatype.")
let (DCon _ _ minName fields) = head cons
(DCon _ _ maxName _) = last cons
pbounded_name = promoteClassName boundedName
fieldsCount = length $ tysOfConFields fields
(minRHS, maxRHS) = case fieldsCount of
0 -> (DConT minName, DConT maxName)
_ ->
let minEqnRHS = foldType (DConT minName)
(replicate fieldsCount (DConT tyminBoundName))
maxEqnRHS = foldType (DConT maxName)
(replicate fieldsCount (DConT tymaxBoundName))
in (minEqnRHS, maxEqnRHS)
return $ [ DInstanceD [] (DConT pbounded_name `DAppT` kindParam kind)
[ DTySynInstD tyminBoundName (DTySynEqn [] minRHS)
, DTySynInstD tymaxBoundName (DTySynEqn [] maxRHS)
]
]
mkBoundedTypeInstance _ _ = fail "Error deriving Bounded instance"