DeprecDecl(..), LDeprecDecl,
HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups,
tcdName, tyClDeclNames, tyClDeclTyVars,
- isClassDecl, isTFunDecl, isSynDecl, isTEqnDecl, isDataDecl,
+ isClassDecl, isTFunDecl, isSynDecl, isDataDecl, isKindSigDecl,
+ isIdxTyDecl,
countTyClDecls,
conDetailsTys,
instDeclATs,
import HsImpExp ( pprHsVar )
import HsTypes
import NameSet ( NameSet )
-import HscTypes ( DeprecTxt )
import CoreSyn ( RuleName )
-import Kind ( Kind, pprKind )
-import BasicTypes ( Activation(..) )
+import {- Kind parts of -} Type ( Kind, pprKind )
+import BasicTypes ( Activation(..), DeprecTxt )
import ForeignCall ( CCallTarget(..), DNCallSpec, CCallConv, Safety,
CExportSpec(..), CLabelString )
-- others:
-import FunDeps ( pprFundeps )
-import Class ( FunDep )
+import Class ( FunDep, pprFundeps )
import Outputable
import Util ( count )
import SrcLoc ( Located(..), unLoc, noLoc )
import FastString
+import Maybe ( isJust )
\end{code}
-- for a module. That's why (despite the misnomer) IfaceSig and ForeignType
-- are both in TyClDecl
+-- Representation of indexed types
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- Kind signatures of indexed types come in two flavours:
+--
+-- * kind signatures for type functions: variant `TyFunction' and
+--
+-- * kind signatures for indexed data types and newtypes : variant `TyData'
+-- iff a kind is present in `tcdKindSig' and there are no constructors in
+-- `tcdCons'.
+--
+-- Indexed types are represented by 'TyData' and 'TySynonym' using the field
+-- 'tcdTyPats::Maybe [LHsType name]', with the following meaning:
+--
+-- * If it is 'Nothing', we have a *vanilla* data type declaration or type
+-- synonym declaration and 'tcdVars' contains the type parameters of the
+-- type constructor.
+--
+-- * If it is 'Just pats', we have the definition of an indexed type Then,
+-- 'pats' are type patterns for the type-indexes of the type constructor
+-- and 'tcdVars' are the variables in those patterns. Hence, the arity of
+-- the indexed type (ie, the number of indexes) is 'length tcdTyPats' and
+-- *not* 'length tcdVars'.
+--
+-- In both cases, 'tcdVars' collects all variables we need to quantify over.
+
type LTyClDecl name = Located (TyClDecl name)
data TyClDecl name
tcdTyVars :: [LHsTyVarBndr name], -- Type variables
tcdTyPats :: Maybe [LHsType name], -- Type patterns
tcdKindSig:: Maybe Kind, -- Optional kind sig;
- -- (only for the 'where' form)
+ -- (only for the
+ -- 'where' form and
+ -- indexed type sigs)
tcdCons :: [LConDecl name], -- Data constructors
-- For data T a = T1 | T2 a the LConDecls all have ResTyH98
| TyFunction {tcdLName :: Located name, -- type constructor
tcdTyVars :: [LHsTyVarBndr name], -- type variables
tcdIso :: Bool, -- injective type?
- tcdKindSig:: Maybe Kind -- result kind
+ tcdKind :: Kind -- result kind
}
| TySynonym { tcdLName :: Located name, -- type constructor
tcdTyVars :: [LHsTyVarBndr name], -- type variables
tcdTyPats :: Maybe [LHsType name], -- Type patterns
+ -- 'Nothing' => vanilla
+ -- type synonym
tcdSynRhs :: LHsType name -- synonym expansion
}
tcdSigs :: [LSig name], -- Methods' signatures
tcdMeths :: LHsBinds name, -- Default methods
tcdATs :: [LTyClDecl name] -- Associated types; ie
- -- only 'TyData'
+ -- only 'TyData',
+ -- 'TyFunction',
-- and 'TySynonym'
}
Simple classifiers
\begin{code}
-isTFunDecl, isDataDecl, isSynDecl, isTEqnDecl, isClassDecl ::
+isTFunDecl, isDataDecl, isSynDecl, isClassDecl, isKindSigDecl, isIdxTyDecl ::
TyClDecl name -> Bool
-- type function kind signature
isClassDecl (ClassDecl {}) = True
isClassDecl other = False
+
+-- kind signature (for an indexed type)
+isKindSigDecl (TyFunction {} ) = True
+isKindSigDecl (TyData {tcdKindSig = Just _,
+ tcdCons = [] }) = True
+isKindSigDecl other = False
+
+-- definition of an instance of an indexed type
+isIdxTyDecl tydecl
+ | isTEqnDecl tydecl = True
+ | isDataDecl tydecl = isJust (tcdTyPats tydecl)
+ | otherwise = False
\end{code}
Dealing with names
-- We use the equality to filter out duplicate field names
tyClDeclNames (TyFunction {tcdLName = name}) = [name]
-tyClDeclNames (TySynonym {tcdLName = name,
- tcdTyPats= Nothing}) = [name]
-tyClDeclNames (TySynonym {} ) = [] -- type equation
+tyClDeclNames (TySynonym {tcdLName = name}) = [name]
tyClDeclNames (ForeignType {tcdLName = name}) = [name]
tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats})
= hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon]
ppr (TyFunction {tcdLName = ltycon, tcdTyVars = tyvars, tcdIso = iso,
- tcdKindSig = mb_sig})
+ tcdKind = kind})
= typeMaybeIso <+> pp_decl_head [] ltycon tyvars Nothing <+>
- ppr_sig mb_sig
+ dcolon <+> pprKind kind
where
typeMaybeIso = if iso
- then ptext SLIT("type iso")
- else ptext SLIT("type")
-
- ppr_sig Nothing = empty
- ppr_sig (Just kind) = dcolon <+> pprKind kind
+ then ptext SLIT("type family iso")
+ else ptext SLIT("type family")
ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats,
tcdSynRhs = mono_ty})
- = hang (ptext SLIT("type") <+> pp_decl_head [] ltycon tyvars typats <+>
+ = hang (ptext SLIT("type") <+>
+ (if isJust typats then ptext SLIT("instance") else empty) <+>
+ pp_decl_head [] ltycon tyvars typats <+>
equals)
4 (ppr mono_ty)
ppr (TyData {tcdND = new_or_data, tcdCtxt = context, tcdLName = ltycon,
tcdTyVars = tyvars, tcdTyPats = typats, tcdKindSig = mb_sig,
tcdCons = condecls, tcdDerivs = derivings})
- = pp_tydecl (ppr new_or_data <+>
+ = pp_tydecl (null condecls && isJust mb_sig)
+ (ppr new_or_data <+>
+ (if isJust typats then ptext SLIT("instance") else empty) <+>
pp_decl_head (unLoc context) ltycon tyvars typats <+>
ppr_sig mb_sig)
(pp_condecls condecls)
pp_condecls cs -- In H98 syntax
= equals <+> sep (punctuate (ptext SLIT(" |")) (map ppr cs))
-pp_tydecl pp_head pp_decl_rhs derivings
+pp_tydecl True pp_head pp_decl_rhs derivings
+ = pp_head
+pp_tydecl False pp_head pp_decl_rhs derivings
= hang pp_head 4 (sep [
- pp_decl_rhs,
- case derivings of
- Nothing -> empty
- Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)]
+ pp_decl_rhs,
+ case derivings of
+ Nothing -> empty
+ Just ds -> hsep [ptext SLIT("deriving"), parens (interpp'SP ds)]
])
instance Outputable NewOrData where
-- figures out the quantified type variables for us.
(LHsBinds name)
[LSig name] -- User-supplied pragmatic info
- [LTyClDecl name]-- Associated types
+ [LTyClDecl name]-- Associated types (ie, 'TyData' and
+ -- 'TySynonym' only)
instance (OutputableBndr name) => Outputable (InstDecl name) where