
Ross Paterson wrote:
On Mon, Nov 20, 2006 at 04:51:29PM +1100, Donald Bruce Stewart wrote:
So the uses fall into 2 categories:
* FFI binding and raw pointer/foreign data manipulation * type equalities known, but not expressible statically
Now, can we say something portable about these uses?
The second group, perhaps, but the first group (unsafeCoerce#) depend on GHC's internal representations.
I'd like to have a precise (sound, if not complete) description of when it's safe to use unsafeCoerce in GHC, but it needs some careful thought. I *think* the following cases are guaranteed to work: * cast that changes a phantom type, or changes a type that is not reflected by a part of the value, eg. 'unsafeCoerce (Left 3) :: Either Int a' should be fine for any 'a', * casting a polymorphic type to the actual type of the runtime value. That is, you can safely cast a value to its correct type. (eg. in Typeable.cast). * casting an unboxed type to another unboxed type of the same size. The difficult cases arise when you want to cast a value to a type other than its real type, such as you need to do in the implementation of Dynamic for example. I doubt that we could provide a portable implementation of Dynamic. Casting boxed types to unboxed types or vice versa is pretty much guaranteed to end in tears. Cheers, Simon