base-4.14.0.0: Basic libraries

Unsafe.Coerce

Synopsis

# Documentation

unsafeCoerce :: forall (a :: Type) (b :: Type). a -> b Source #

Coerce a value from one type to another, bypassing the type-checker.

There are several legitimate ways to use unsafeCoerce:

1. To coerce e.g. Int to HValue, put it in a list of HValue, and then later coerce it back to Int before using it.
2. To produce e.g. (a+b) :~: (b+a) from unsafeCoerce Refl. Here the two sides really are the same type -- so nothing unsafe is happening -- but GHC is not clever enough to see it.
3. In Data.Typeable we have
       eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
eqTypeRep a b
| sameTypeRep a b = Just (unsafeCoerce HRefl)
| otherwise       = Nothing


Here again, the unsafeCoerce HRefl is safe, because the two types really are the same -- but the proof of that relies on the complex, trusted implementation of Typeable.

1. The "reflection trick", which takes advantanage of the fact that in class C a where { op :: ty }, we can safely coerce between C a and ty (which have different kinds!) because it's really just a newtype. Note: there is no guarantee, at all that this behavior will be supported into perpetuity.

unsafeCoerceUnlifted :: forall (a :: TYPE 'UnliftedRep) (b :: TYPE 'UnliftedRep). a -> b Source #

This type is treated magically within GHC. Any pattern match of the form case unsafeEqualityProof of UnsafeRefl -> body gets transformed just into body. This is ill-typed, but the transformation takes place after type-checking is complete. It is used to implement unsafeCoerce. You probably don't want to use UnsafeRefl in an expression, but you might conceivably want to pattern-match on it. Use unsafeEqualityProof to create one of these.