module HsDecls (
HsDecl(..), LHsDecl, TyClDecl(..), LTyClDecl,
InstDecl(..), LInstDecl, DerivDecl(..), LDerivDecl, NewOrData(..),
+ FamilyFlavour(..),
RuleDecl(..), LRuleDecl, RuleBndr(..),
DefaultDecl(..), LDefaultDecl, SpliceDecl(..),
ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..),
CImportSpec(..), FoType(..),
ConDecl(..), ResType(..), LConDecl,
- DocDecl(..), LDocDecl, docDeclDoc, DocEntity(..),
+ DocDecl(..), LDocDecl, docDeclDoc,
DeprecDecl(..), LDeprecDecl,
HsGroup(..), emptyRdrGroup, emptyRnGroup, appendGroups,
tcdName, tyClDeclNames, tyClDeclTyVars,
- isClassDecl, isTFunDecl, isSynDecl, isDataDecl, isKindSigDecl,
- isIdxTyDecl,
+ isClassDecl, isSynDecl, isDataDecl, isTypeDecl, isFamilyDecl,
+ isFamInstDecl,
countTyClDecls,
conDetailsTys,
instDeclATs,
hs_depds :: [LDeprecDecl id],
hs_ruleds :: [LRuleDecl id],
- hs_docs :: [DocEntity id]
- -- Used to remember the module structure,
- -- which is needed to produce Haddock documentation
+ hs_docs :: [LDocDecl id]
}
emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a
\begin{code}
-- 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'.
+-- Family kind signatures are represented by the variant `TyFamily'. It
+-- covers "type family", "newtype family", and "data family" declarations,
+-- distinguished by the value of the field `tcdFlavour'.
--
-- Indexed types are represented by 'TyData' and 'TySynonym' using the field
-- 'tcdTyPats::Maybe [LHsType name]', with the following meaning:
-- 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,
+-- * 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
+-- and 'tcdTyVars' 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'.
--
tcdLName :: Located name,
tcdExtName :: Maybe FastString,
tcdFoType :: FoType
- }
+ }
+ -- type/data/newtype family T :: *->*
+ | TyFamily { tcdFlavour:: FamilyFlavour, -- type, new, or data
+ tcdLName :: Located name, -- type constructor
+ tcdTyVars :: [LHsTyVarBndr name], -- type variables
+ tcdKind :: Maybe Kind -- result kind
+ }
+
+ -- Declares a data type or newtype, giving its construcors
+ -- data/newtype T a = <constrs>
+ -- data/newtype instance T [a] = <constrs>
| TyData { tcdND :: NewOrData,
tcdCtxt :: LHsContext name, -- Context
tcdLName :: Located name, -- Type constructor
+
tcdTyVars :: [LHsTyVarBndr name], -- Type variables
+
tcdTyPats :: Maybe [LHsType name], -- Type patterns
- tcdKindSig:: Maybe Kind, -- Optional kind sig;
- -- (only for the
- -- 'where' form and
- -- indexed type sigs)
+ -- Just [t1..tn] for data instance T t1..tn = ...
+ -- in this case tcdTyVars = fv( tcdTyPats )
+ -- Nothing for everything else
+
+ tcdKindSig:: Maybe Kind, -- Optional kind sig
+ -- (Just k) for a GADT-style 'data', or 'data
+ -- instance' decl with explicit kind sig
tcdCons :: [LConDecl name], -- Data constructors
-- For data T a = T1 | T2 a the LConDecls all have ResTyH98
-- are non-empty for the newtype-deriving case
}
- | TyFunction {tcdLName :: Located name, -- type constructor
- tcdTyVars :: [LHsTyVarBndr name], -- type variables
- tcdIso :: Bool, -- injective type?
- 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
+ -- See comments for tcdTyPats in TyData
+ -- 'Nothing' => vanilla type synonym
+
tcdSynRhs :: LHsType name -- synonym expansion
}
-- only 'TyData',
-- 'TyFunction',
-- and 'TySynonym'
- tcdDocs :: [DocEntity name] -- Haddock docs
+ tcdDocs :: [LDocDecl name] -- Haddock docs
}
data NewOrData
- = NewType -- "newtype Blah ..."
- | DataType -- "data Blah ..."
- deriving( Eq ) -- Needed because Demand derives Eq
+ = NewType -- "newtype Blah ..."
+ | DataType -- "data Blah ..."
+ deriving( Eq ) -- Needed because Demand derives Eq
+
+data FamilyFlavour
+ = TypeFamily -- "type family ..."
+ | DataFamily NewOrData -- "newtype family ..." or "data family ..."
\end{code}
Simple classifiers
\begin{code}
-isTFunDecl, isDataDecl, isSynDecl, isClassDecl, isKindSigDecl, isIdxTyDecl ::
+isDataDecl, isTypeDecl, isSynDecl, isClassDecl, isFamilyDecl, isFamInstDecl ::
TyClDecl name -> Bool
--- type function kind signature
-isTFunDecl (TyFunction {}) = True
-isTFunDecl other = False
-
--- vanilla Haskell type synonym
-isSynDecl (TySynonym {tcdTyPats = Nothing}) = True
-isSynDecl other = False
+-- data/newtype or data/newtype instance declaration
+isDataDecl (TyData {}) = True
+isDataDecl _other = False
--- type equation (of a type function)
-isTEqnDecl (TySynonym {tcdTyPats = Just _}) = True
-isTEqnDecl other = False
+-- type or type instance declaration
+isTypeDecl (TySynonym {}) = True
+isTypeDecl _other = False
-isDataDecl (TyData {}) = True
-isDataDecl other = False
+-- vanilla Haskell type synonym (ie, not a type instance)
+isSynDecl (TySynonym {tcdTyPats = Nothing}) = True
+isSynDecl _other = False
+-- type class
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
+-- type family declaration
+isFamilyDecl (TyFamily {}) = True
+isFamilyDecl _other = False
+
+-- family instance (types, newtypes, and data types)
+isFamInstDecl tydecl
+ | isTypeDecl tydecl
+ || isDataDecl tydecl = isJust (tcdTyPats tydecl)
+ | otherwise = False
\end{code}
Dealing with names
-- For record fields, the first one counts as the SrcLoc
-- We use the equality to filter out duplicate field names
-tyClDeclNames (TyFunction {tcdLName = name}) = [name]
+tyClDeclNames (TyFamily {tcdLName = name}) = [name]
tyClDeclNames (TySynonym {tcdLName = name}) = [name]
tyClDeclNames (ForeignType {tcdLName = name}) = [name]
tyClDeclNames (TyData {tcdLName = tc_name, tcdCons = cons})
= tc_name : conDeclsNames (map unLoc cons)
-tyClDeclTyVars (TyFunction {tcdTyVars = tvs}) = tvs
+tyClDeclTyVars (TyFamily {tcdTyVars = tvs}) = tvs
tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs
tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs
tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs
\begin{code}
countTyClDecls :: [TyClDecl name] -> (Int, Int, Int, Int, Int, Int)
- -- class, synonym decls, type function signatures,
- -- type function equations, data, newtype
+ -- class, synonym decls, data, newtype, family decls, family instances
countTyClDecls decls
- = (count isClassDecl decls,
- count isSynDecl decls,
- count isTFunDecl decls,
- count isTEqnDecl decls,
- count isDataTy decls,
- count isNewTy decls)
+ = (count isClassDecl decls,
+ count isSynDecl decls, -- excluding...
+ count isDataTy decls, -- ...family...
+ count isNewTy decls, -- ...instances
+ count isFamilyDecl decls,
+ count isFamInstDecl decls)
where
- isDataTy TyData{tcdND=DataType} = True
- isDataTy _ = False
+ isDataTy TyData{tcdND = DataType, tcdTyPats = Nothing} = True
+ isDataTy _ = False
- isNewTy TyData{tcdND=NewType} = True
- isNewTy _ = False
+ isNewTy TyData{tcdND = NewType, tcdTyPats = Nothing} = True
+ isNewTy _ = False
\end{code}
\begin{code}
ppr (ForeignType {tcdLName = ltycon})
= hsep [ptext SLIT("foreign import type dotnet"), ppr ltycon]
- ppr (TyFunction {tcdLName = ltycon, tcdTyVars = tyvars, tcdIso = iso,
- tcdKind = kind})
- = typeMaybeIso <+> pp_decl_head [] ltycon tyvars Nothing <+>
- dcolon <+> pprKind kind
+ ppr (TyFamily {tcdFlavour = flavour, tcdLName = ltycon,
+ tcdTyVars = tyvars, tcdKind = mb_kind})
+ = pp_flavour <+> pp_decl_head [] ltycon tyvars Nothing <+> pp_kind
where
- typeMaybeIso = if iso
- then ptext SLIT("type family iso")
- else ptext SLIT("type family")
+ pp_flavour = case flavour of
+ TypeFamily -> ptext SLIT("type family")
+ DataFamily NewType -> ptext SLIT("newtype family")
+ DataFamily DataType -> ptext SLIT("data family")
+
+ pp_kind = case mb_kind of
+ Nothing -> empty
+ Just kind -> dcolon <+> pprKind kind
ppr (TySynonym {tcdLName = ltycon, tcdTyVars = tyvars, tcdTyPats = typats,
tcdSynRhs = mono_ty})
\begin{code}
type LDerivDecl name = Located (DerivDecl name)
-data DerivDecl name
- = DerivDecl (LHsType name) (Located name)
+data DerivDecl name = DerivDecl (LHsType name)
instance (OutputableBndr name) => Outputable (DerivDecl name) where
- ppr (DerivDecl ty n)
- = hsep [ptext SLIT("deriving"), ppr ty, ptext SLIT("for"), ppr n]
+ ppr (DerivDecl ty)
+ = hsep [ptext SLIT("derived instance"), ppr ty]
\end{code}
%************************************************************************
\begin{code}
--- source code entities, for representing the module structure
-data DocEntity name
- = DeclEntity name
- | DocEntity (DocDecl name)
-
type LDocDecl name = Located (DocDecl name)
data DocDecl name