
John Meacham wrote:
On Mon, Nov 20, 2006 at 02:45:13PM +0000, Malcolm Wallace wrote:
Simon Marlow
wrote: Now, can we say something portable about these uses?
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.
And not just GHC. I think all the points you mention (below) would be entirely reasonable for all implementations.
* 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.
There is one more important use case you haven't mentioned:
* casting from a newtype to the contained value (or vice versa).
This latter type of cast is the only one I can remember ever having used myself.
there are very few safe uses of unsafeCoerce in jhc. the only ones guarenteed safe are
* casting a recursive newtype to its representation and back (note, recursive newtypes are chosen via a loop-breaking algorithm in the compiler, so it is best to let it worry about this) * casting arbitrary values of kind * to a system provided type 'Box' and back again * casting arbitrary values of kind ! (the kind of strict boxed values) to a system provided type 'BoxBang' and back again
Is kind ! visible to the programmer? How? What are you allowed/not allowed to do with something of kind !? I added a kind ! to GHC recently, but it has a very limited use: it's the kind of boxed/unlifted primitive types like ByteArray# and MutVar#. So you can write polymorphic functions over boxed/unlifted things, and one day maybe have arrays of them. Cheers, Simon