th-typegraph-0.25: Language/Haskell/TH/TypeGraph/Arity.hs
-- | Function to compute the arity or kind of a Type, the number of
-- type parameters that need to be applied to get a concrete type.
module Language.Haskell.TH.TypeGraph.Arity
( typeArity
) where
import Language.Haskell.TH
import Language.Haskell.TH.Desugar ({- instances -})
import Language.Haskell.TH.Syntax (Quasi(qReify))
import Language.Haskell.TH.TypeGraph.Prelude (pprint')
-- | Compute the arity of a type - the number of type parameters that
-- must be applied to it in order to obtain a concrete type. I'm not
-- quite sure I understand the relationship between this and
-- 'freeTypeVars'.
typeArity :: Quasi m => Type -> m Int
typeArity (ForallT _ _ typ) = typeArity typ -- Shouldn't a forall affect the arity?
typeArity ListT = return 1
typeArity (TupleT n) = return n
typeArity (VarT _) = return 1
typeArity (AppT t _) = typeArity t >>= \ n -> return $ n - 1
typeArity (ConT name) = qReify name >>= infoArity
where
infoArity (TyConI dec) = decArity dec
infoArity (PrimTyConI _ _ _) = return 0
infoArity (FamilyI dec _) = decArity dec
infoArity info = error $ "typeArity - unexpected: " ++ pprint' info
decArity (DataD _ _ vs _ _) = return $ length vs
decArity (NewtypeD _ _ vs _ _) = return $ length vs
decArity (TySynD _ vs t) = typeArity t >>= \ n -> return $ n + length vs
decArity (FamilyD _ _ vs _mk) = return $ {- not sure what to do with the kind mk here -} length vs
decArity dec = error $ "decArity - unexpected: " ++ show dec
typeArity typ = error $ "typeArity - unexpected type: " ++ show typ