base-4.20.0.0: Core data structures and operations
Safe HaskellNone
LanguageHaskell2010

Unsafe.Coerce

Synopsis

Documentation

unsafeCoerce :: a -> b Source #

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

There are several legitimate ways to use unsafeCoerce:

  1. To coerce a lifted type such as Int to Any, put it in a list of Any, 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. (superseded) The "reflection trick", which takes advantage 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. It is now preferred to use withDict in GHC.Magic.Dict, which is type-safe. See Note [withDict] in GHC.Tc.Instance.Class for details.
  2. (superseded) Casting between two types which have exactly the same structure: between a newtype of T and T, or between types which differ only in "phantom" type parameters. It is now preferred to use coerce from Data.Coerce, which is type-safe.

Other uses of unsafeCoerce are undefined. In particular, you should not use unsafeCoerce to cast a T to an algebraic data type D, unless T is also an algebraic data type. For example, do not cast Int->Int to Bool, even if you later cast that Bool back to Int->Int before applying it. The reasons have to do with GHC's internal representation details (for the cognoscenti, data values can be entered but function closures cannot). If you want a safe type to cast things to, use Any, which is not an algebraic data type.

unsafeCoerceUnlifted :: forall (a :: UnliftedType) (b :: UnliftedType). a -> b Source #

unsafeCoerceAddr :: forall (a :: TYPE 'AddrRep) (b :: TYPE 'AddrRep). a -> b Source #

unsafeEqualityProof :: forall {k} (a :: k) (b :: k). UnsafeEquality a b Source #

data UnsafeEquality (a :: k) (b :: k) where 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.

Constructors

UnsafeRefl :: forall {k} (a :: k). UnsafeEquality a a 

unsafeCoerce# :: a -> b Source #

Highly, terribly dangerous coercion from one representation type to another. Misuse of this function can invite the garbage collector to trounce upon your data and then laugh in your face. You don't want this function. Really.

This becomes more obvious when looking at its actual type: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). a -> b Which often get's rendered as a -> b in haddock for technical reasons.