Main data types representing Types

Types are one of:

Unboxed

Iff its representation is other than a pointer
Unboxed types are also unlifted.

Lifted

Iff it has bottom as an element.
Closures always have lifted types: i.e. any
let-bound identifier in Core must have a lifted
type. Operationally, a lifted object is one that
can be entered.
Only lifted types may be unified with a type variable.

Algebraic

Iff it is a type with one or more constructors, whether
declared with data or newtype.
An algebraic type is one that can be deconstructed
with a case expression. This is not the same as
lifted types, because we also include unboxed
tuples in this classification.

Data

Iff it is a type declared with data, or a boxed tuple.

Primitive

Iff it is a built-in type that can't be expressed in Haskell.

Currently, all primitive types are unlifted, but that's not necessarily
the case: for example, Int could be primitive.

Some primitive types are unboxed, such as Int#, whereas some are boxed
but unlifted (such as ByteArray#). The only primitive types that we
classify as algebraic are the unboxed tuples.

Some examples of type classifications that may make this a bit clearer are:

A source type is a type that is a separate type as far as the type checker is
concerned, but which has a more low-level representation as far as Core-to-Core
passes and the rest of the back end is concerned. Notably, PredTys are removed
from the representation type while they do exist in the source types.

You don't normally have to worry about this, as the utility functions in
this module will automatically convert a source into a representation type
if they are spotted, to the best of it's abilities. If you don't want this
to happen, use the equivalent functions from the TcType module.

Recursively splits a type as far as is possible, leaving a residual
type being applied to and the type arguments applied to it. Never fails,
even if that means returning an empty list of type applications.

Splits off argument types from the given type and associating
them with the things in the input list from left to right. The
final result type is returned, along with the resulting pairs of
objects and types, albeit with the list of pairs in reverse order.
Panics if there are not enough argument types for the input list.

See Type for what an algebraic type is.
Should only be applied to types, as opposed to e.g. partially
saturated type constructors. Closed type constructors are those
with a fixed right hand side, as opposed to e.g. associated types

Computes whether an argument (or let right hand side) should
be computed strictly or lazily, based only on its type.
Works just like isUnLiftedType, except that it has a special case
for dictionaries (i.e. does not work purely on representation types)

Expand out all type synonyms. Actually, it'd suffice to expand out
just the ones that discard type variables (e.g. type Funny a = Int)
But we don't know which those are currently, so we just expand all.