+ -- [] means "no information, assume the worst"
+
+data AlgTyConRhs
+ = AbstractTyCon -- We know nothing about this data type, except
+ -- that it's represented by a pointer
+ -- Used when we export a data type abstractly into
+ -- an hi file
+
+ | DataTyCon {
+ data_cons :: [DataCon],
+ -- The constructors; can be empty if the user declares
+ -- the type to have no constructors
+ -- INVARIANT: Kept in order of increasing tag
+ -- (see the tag assignment in DataCon.mkDataCon)
+ is_enum :: Bool -- Cached: True <=> an enumeration type
+ } -- Includes data types with no constructors.
+
+ | NewTyCon {
+ data_con :: DataCon, -- The unique constructor; it has no existentials
+
+ nt_rhs :: Type, -- Cached: the argument type of the constructor
+ -- = the representation type of the tycon
+
+ nt_etad_rhs :: ([TyVar], Type) ,
+ -- The same again, but this time eta-reduced
+ -- hence the [TyVar] which may be shorter than the declared
+ -- arity of the TyCon. See Note [Newtype eta]
+
+ nt_rep :: Type -- Cached: the *ultimate* representation type
+ -- By 'ultimate' I mean that the top-level constructor
+ -- of the rep type is not itself a newtype or type synonym.
+ -- The rep type isn't entirely simple:
+ -- for a recursive newtype we pick () as the rep type
+ -- newtype T = MkT T
+ --
+ -- This one does not need to be eta reduced; hence its
+ -- free type variables are conveniently tyConTyVars
+ -- Thus:
+ -- newtype T a = MkT [(a,Int)]
+ -- The rep type is [(a,Int)]
+ -- NB: the rep type isn't necessarily the original RHS of the
+ -- newtype decl, because the rep type looks through other
+ } -- newtypes.
+
+visibleDataCons :: AlgTyConRhs -> [DataCon]
+visibleDataCons AbstractTyCon = []
+visibleDataCons (DataTyCon{ data_cons = cs }) = cs
+visibleDataCons (NewTyCon{ data_con = c }) = [c]
+\end{code}
+
+Note [Newtype eta]
+~~~~~~~~~~~~~~~~~~
+Consider
+ newtype Parser m a = MkParser (Foogle m a)
+Are these two types equal (to Core)?
+ Monad (Parser m)
+ Monad (Foogle m)
+Well, yes. But to see that easily we eta-reduce the RHS type of
+Parser, in this case to ([], Froogle), so that even unsaturated applications
+of Parser will work right. This eta reduction is done when the type
+constructor is built, and cached in NewTyCon. The cached field is
+only used in coreExpandTyCon_maybe.
+
+Here's an example that I think showed up in practice
+Source code:
+ newtype T a = MkT [a]
+ newtype Foo m = MkFoo (forall a. m a -> Int)
+
+ w1 :: Foo []
+ w1 = ...
+
+ w2 :: Foo T
+ w2 = MkFoo (\(MkT x) -> case w1 of MkFoo f -> f x)
+
+After desugaring, and discading the data constructors for the newtypes,
+we get:
+ w2 :: Foo T
+ w2 = w1
+And now Lint complains unless Foo T == Foo [], and that requires T==[]
+
+
+%************************************************************************
+%* *
+\subsection{PrimRep}
+%* *
+%************************************************************************
+
+A PrimRep is an abstraction of a type. It contains information that
+the code generator needs in order to pass arguments, return results,
+and store values of this type.
+
+A PrimRep is somewhat similar to a CgRep (see codeGen/SMRep) and a
+MachRep (see cmm/MachOp), although each of these types has a distinct
+and clearly defined purpose:
+
+ - A PrimRep is a CgRep + information about signedness + information
+ about primitive pointers (AddrRep). Signedness and primitive
+ pointers are required when passing a primitive type to a foreign
+ function, but aren't needed for call/return conventions of Haskell
+ functions.
+
+ - A MachRep is a basic machine type (non-void, doesn't contain
+ information on pointerhood or signedness, but contains some
+ reps that don't have corresponding Haskell types).
+
+\begin{code}
+data PrimRep
+ = VoidRep
+ | PtrRep
+ | IntRep -- signed, word-sized
+ | WordRep -- unsinged, word-sized
+ | Int64Rep -- signed, 64 bit (32-bit words only)
+ | Word64Rep -- unsigned, 64 bit (32-bit words only)
+ | AddrRep -- a pointer, but not to a Haskell value
+ | FloatRep
+ | DoubleRep