+ {\tt par x y = case (par\# x) of \_ -> lazy y}
+
+ If {\tt lazy} were not lazy, {\tt par} would look strict in {\tt y} which
+ would defeat the whole purpose of {\tt par}.
+
+ Like {\tt seq}, the argument of {\tt lazy} can have an unboxed type. }
+
+primtype Any a
+ { The type constructor {\tt Any} is type to which you can unsafely coerce any
+ lifted type, and back.
+
+ * It is lifted, and hence represented by a pointer
+
+ * It does not claim to be a {\it data} type, and that's important for
+ the code generator, because the code gen may {\it enter} a data value
+ but never enters a function value.
+
+ It's also used to instantiate un-constrained type variables after type
+ checking. For example
+
+ {\tt length Any []}
+
+ Annoyingly, we sometimes need {\tt Any}s of other kinds, such as {\tt (* -> *)} etc.
+ This is a bit like tuples. We define a couple of useful ones here,
+ and make others up on the fly. If any of these others end up being exported
+ into interface files, we'll get a crash; at least until we add interface-file
+ syntax to support them. }
+
+pseudoop "unsafeCoerce#"
+ a -> b
+ { The function {\tt unsafeCoerce\#} allows you to side-step the typechecker entirely. That
+ is, it allows you to coerce any type into any other type. If you use this function,
+ you had better get it right, otherwise segmentation faults await. It is generally
+ used when you want to write a program that you know is well-typed, but where Haskell's
+ type system is not expressive enough to prove that it is well typed.
+
+ The following uses of {\tt unsafeCoerce\#} are supposed to work (i.e. not lead to
+ spurious compile-time or run-time crashes):
+
+ * Casting any lifted type to {\tt Any}
+
+ * Casting {\tt Any} back to the real type
+
+ * Casting an unboxed type to another unboxed type of the same size
+ (but not coercions between floating-point and integral types)
+
+ * Casting between two types that have the same runtime representation. One case is when
+ the two types differ only in "phantom" type parameters, for example
+ {\tt Ptr Int} to {\tt Ptr Float}, or {\tt [Int]} to {\tt [Float]} when the list is
+ known to be empty. Also, a {\tt newtype} of a type {\tt T} has the same representation
+ at runtime as {\tt T}.
+
+ Other uses of {\tt unsafeCoerce\#} are undefined. In particular, you should not use
+ {\tt unsafeCoerce\#} to cast a T to an algebraic data type D, unless T is also
+ an algebraic data type. For example, do not cast {\tt Int->Int} to {\tt Bool}, even if
+ you later cast that {\tt Bool} back to {\tt Int->Int} before applying it. The reasons
+ have to do with GHC's internal representation details (for the congnoscenti, data values
+ can be entered but function closures cannot). If you want a safe type to cast things
+ to, use {\tt Any}, which is not an algebraic data type.
+
+ }
+
+-- NB. It is tempting to think that casting a value to a type that it doesn't have is safe
+-- as long as you don't "do anything" with the value in its cast form, such as seq on it. This
+-- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type,
+-- Bad Things Might Happen. See bug #1616: in this case we cast a function of type (a,b) -> (a,b)
+-- to () -> () and back again. The strictness analyser saw that the function was strict, but
+-- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed
+-- a new (), with the result that the code ended up with "case () of (a,b) -> ...".