module Data.Comp.Trans.Names
(
standardNameSet
, baseTypes
, getLab
, transName
, nameLab
, smartConstrName
, modNameBase
, simplifyDataInf
) where
import Control.Lens ( (^.), _3 )
import Control.Monad ( liftM2 )
import Data.Functor ( (<$>) )
import Data.Set ( Set, fromList )
import Language.Haskell.TH.Syntax
standardNameSet :: Set Name
standardNameSet = fromList [''Maybe, ''Int, ''Integer, ''Bool, ''Char, ''Double]
baseTypes :: [Type]
baseTypes = [ ConT ''Int
, ConT ''Bool
, ConT ''Char
, ConT ''Double
, ConT ''Integer
, ConT ''String
, AppT ListT (ConT ''Char)
]
getLab :: Type -> Q Type
getLab (AppT f@(AppT _ _) t) = liftM2 AppT (getLab f) (getLab t)
getLab (AppT f t) = AppT f <$> getLab t
getLab ListT = return ListT
getLab (TupleT n) = return $ TupleT n
getLab (ConT n) = return $ ConT $ nameLab n
getLab _ = fail "When deriving multi-sorted compositional data type, found unsupported type in AST."
transName :: Name -> Name
transName = modNameBase id
nameLab :: Name -> Name
nameLab = modNameBase (++"L")
smartConstrName :: Name -> Name
smartConstrName = modNameBase ('i':)
modNameBase :: (String -> String) -> Name -> Name
modNameBase f = mkName . f . nameBase
simplifyDataInf :: Info -> [(Name, [Type])]
simplifyDataInf (TyConI (DataD _ _ _ cons _)) = map extractCon cons
simplifyDataInf (TyConI (NewtypeD _ _ _ con _)) = [extractCon con]
simplifyDataInf _ = error "Attempted to derive multi-sorted compositional data type for non-nullary datatype"
extractCon :: Con -> (Name, [Type])
extractCon (NormalC nm sts) = (nm, map snd sts)
extractCon (RecC nm vsts) = (nm, map (^. _3) vsts)
extractCon (ForallC _ _ c) = extractCon c
extractCon _ = error "Unsupported constructor type encountered"