
The docs for unsafeCoerce# say: "The following uses of unsafeCoerce# are supposed to work (i.e. not lead to spurious compile-time or run-time crashes): # Casting any lifted type to Any # Casting 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) ..." My experience so far is consistent with the assumption that e.g. unsafeCoerce# :: Word64 -> Double is like a cast from (uint64_t *) to (double *), i.e. a bit-pattern- preserving transformation (although by the docs, that use is undefined). Would that assumption generally hold for unsafeCoerce :: a -> b where a and b are single constructor data types wrapping unboxed types of the same bit-size and hence the use of unsafeCoerce# between such types would produce reliable results *on the same machine with the same OS (and GHC version?)* ? And what about e.g. unsafeCoerce# :: Word64# -> Double# ? By the docs, that isn't supposed to work. Is it not supposed to work only because it's not value-preserving (unsafeCoerce# 1## /=## 1.0##) or are there more pitfalls? If there are more pitfalls, is there any chance of getting a function which reinterprets the bit-patterns? Thanks, Daniel