X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fcomm%2Fthe-beast%2Ftypes.html;fp=docs%2Fcomm%2Fthe-beast%2Ftypes.html;h=383b71f0548dfa48fc9af260f4c6757d84481924;hp=0000000000000000000000000000000000000000;hb=0065d5ab628975892cea1ec7303f968c3338cbe1;hpb=28a464a75e14cece5db40f2765a29348273ff2d2 diff --git a/docs/comm/the-beast/types.html b/docs/comm/the-beast/types.html new file mode 100644 index 0000000..383b71f --- /dev/null +++ b/docs/comm/the-beast/types.html @@ -0,0 +1,179 @@ + + + + + The GHC Commentary - Hybrid Types + + + +

The GHC Commentary - Hybrid Types

+

+ GHC essentially supports two type systems: (1) the source type + system (which is a heavily extended version of the type system of + Haskell 98) and (2) the Core type system, which is the type system + used by the intermediate language (see also Sugar Free: From Haskell To Core). +

+

+ During parsing and renaming, type information is represented in a form + that is very close to Haskell's concrete syntax; it is defined by + HsTypes.HsType. In addition, type, class, and instance + declarations are maintained in their source form as defined in the + module HsDecl. The situation changes during type checking, + where types are translated into a second representation, which is + defined in the module types/TypeRep.lhs, as type + Type. This second representation is peculiar in that it is + a hybrid between the source representation of types and the Core + representation of types. Using functions, such as + Type.coreView and Type.deepCoreView, a value + of type Type exhibits its Core representation. On the + other hand, pretty printing a Type with + TypeRep.pprType yields the type's source representation. +

+

+ In fact, the type checker maintains type + environments based on Type, but needs to perform type + checking on source-level types. As a result, we have functions + Type.tcEqType and Type.tcCmpType, which + compare types based on their source representation, as well as the + function coreEqType, which compares them based on their + core representation. The latter is needed during type checking of Core + (as performed by the functions in the module + coreSyn/CoreLint.lhs). +

+ +

Type Synonyms

+

+ Type synonyms in Haskell are essentially a form of macro definitions on + the type level. For example, when the type checker compares two type + terms, synonyms are always compared in their expanded form. However, to + produce good error messages, we like to avoid expanding type synonyms + during pretty printing. Hence, Type has a variant + NoteTy TyNote Type, where +

+
+
+data TyNote
+  = FTVNote TyVarSet	-- The free type variables of the noted expression
+
+  | SynNote Type	-- Used for type synonyms
+			-- The Type is always a TyConApp, and is the un-expanded form.
+			-- The type to which the note is attached is the expanded form.
+
+

+ In other words, a NoteTy represents the expanded form of a + type synonym together with a note stating its source form. +

+ +

Creating Representation Types of Synonyms

+

+ During translation from HsType to Type the + function Type.mkSynTy is used to construct representations + of applications of type synonyms. It creates a NoteTy node + if the synonym is applied to a sufficient number of arguments; + otherwise, it builds a simple TyConApp and leaves it to + TcMType.checkValidType to pick up invalid unsaturated + synonym applications. While creating a NoteTy, + mkSynTy also expands the synonym by substituting the type + arguments for the parameters of the synonym definition, using + Type.substTyWith. +

+

+ The function mkSynTy is used indirectly via + mkGenTyConApp, mkAppTy, and + mkAppTy, which construct type representations involving + type applications. The function mkSynTy is also used + directly during type checking interface files; this is for tedious + reasons to do with forall hoisting - see the comment at + TcIface.mkIfTcApp. +

+ +

Newtypes

+

+ Data types declared by a newtype declarations constitute new + type constructors---i.e., they are not just type macros, but introduce + new type names. However, provided that a newtype is not recursive, we + still want to implement it by its representation type. GHC realises this + by providing two flavours of type equality: (1) tcEqType is + source-level type equality, which compares newtypes and + PredTypes by name, and (2) coreEqType compares + them structurally (by using deepCoreView to expand the + representation before comparing). The function + deepCoreView (via coreView) invokes + expandNewTcApp for every type constructor application + (TyConApp) to determine whether we are looking at a newtype + application that needs to be expanded to its representation type. +

+ +

Predicates

+

+ The dictionary translation of type classes, translates each predicate in + a type context of a type signature into an additional argument, which + carries a dictionary with the functions overloaded by the corresponding + class. The Type data type has a special variant + PredTy PredType for predicates, where +

+
+
+data PredType 
+  = ClassP Class [Type]		-- Class predicate
+  | IParam (IPName Name) Type	-- Implicit parameter
+
+

+ These types need to be handled as source type during type checking, but + turn into their representations when inspected through + coreView. The representation is determined by + Type.predTypeRep. +

+ +

Representation of Type Constructors

+

+ Type constructor applications are represented in Type by + the variant TyConApp :: TyCon -> [Type] -> Type. The first + argument to TyConApp, namely TyCon.TyCon, + distinguishes between function type constructors (variant + FunTyCon) and algebraic type constructors (variant + AlgTyCon), which arise from data and newtype declarations. + The variant AlgTyCon contains all the information available + from the data/newtype declaration as well as derived information, such + as the Unique and argument variance information. This + includes a field algTcRhs :: AlgTyConRhs, where + AlgTyConRhs distinguishes three kinds of algebraic data + type declarations: (1) declarations that have been exported abstractly, + (2) data declarations, and (3) newtype + declarations. The last two both include their original right hand side; + in addition, the third variant also caches the "ultimate" representation + type, which is the right hand side after expanding all type synonyms and + non-recursive newtypes. +

+

+ Both data and newtype declarations refer to their data constructors + represented as DataCon.DataCon, which include all details + of their signature (as derived from the original declaration) as well + information for code generation, such as their tag value. +

+ +

Representation of Classes and Instances

+

+ Class declarations turn into values of type Class.Class. + They represent methods as the Ids of the dictionary + selector functions. Similar selector functions are available for + superclass dictionaries. +

+

+ Instance declarations turn into values of type + InstEnv.Instance, which in interface files are represented + as IfaceSyn.IfaceInst. Moreover, the type + InstEnv.InstEnv, which is a synonym for UniqFM + ClsInstEnv, provides a mapping of classes to their + instances---ClsInstEnv is essentially a list of instance + declarations. +

+ +

+ +Last modified: Sun Jun 19 13:07:22 EST 2005 + +

+ +