| 87 | == Classifying types == |

| 88 | |

| 89 | GHC uses the following nomenclature for types: |

| 90 | |

| 91 | '''Unboxed''':: a type is unboxed iff its representation is other than a pointer. Unboxed types are also unlifted. |

| 92 | |

| 93 | '''Lifted''':: a type is 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. |

| 94 | |

| 95 | '''Data''':: A type declared with '''{{{data}}}'''. Also boxed tuples. |

| 96 | |

| 97 | '''Algebraic''':: an algebraic data type is a data 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. "Algebraic" is '''NOT''' the same as "lifted", because unboxed tuples count as "algebraic". |

| 98 | |

| 99 | '''Primitive''': a type is primitive iff it is a built-in type that can't be expressed in Haskell. |

| 100 | |

| 101 | Currently, all primitive types are unlifted, but that's not necessarily the case. (E.g. Int could be primitive.) |

| 102 | |

| 103 | 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. |

| 104 | |

| 105 | Examples of type classifications: |

| 106 | |

| 107 | || '''Type''' || '''Primitive''' || '''Boxed''' || '''Lifted''' || '''Algebraic''' || |

| 108 | || `Int#` || Yes || No || No || No || |

| 109 | || `ByteArray#` || Yes || Yes || No || No || |

| 110 | || `(# a, b #)` || Yes || No || No || Yes || |

| 111 | || `( a, b )` || No || Yes || Yes || Yes || |

| 112 | || `[a]` || No || Yes || Yes || Yes || |

| 113 | |