base-4.18.1.0: Basic libraries

Safe Haskell | Unsafe
Language | Haskell2010

Unsafe.Coerce

Synopsis

- unsafeCoerce :: forall (a :: Type) (b :: Type). a -> b
- unsafeCoerceUnlifted :: forall (a :: TYPE ('BoxedRep 'Unlifted)) (b :: TYPE ('BoxedRep 'Unlifted)). a -> b
- unsafeCoerceAddr :: forall (a :: TYPE 'AddrRep) (b :: TYPE 'AddrRep). a -> b
- unsafeEqualityProof :: forall a b. UnsafeEquality a b
- data UnsafeEquality a b where
  - UnsafeRefl :: UnsafeEquality a a
- unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). a -> b

# 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 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.

For safe zero-cost coercions you can instead use the `coerce` function from Data.Coerce.

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

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

unsafeEqualityProof :: forall a b. UnsafeEquality a b Source #

data UnsafeEquality a b 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 :: UnsafeEquality a a |

unsafeCoerce# :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). 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.