[Haskell-cafe] What is the right way to use unsafeCoerce?

Cosmia Fu cosmiafu at gmail.com
Tue Aug 14 02:46:29 UTC 2018

Hi all,

I have noticed that unsafeCoerce is able to

> Prelude> import Unsafe.Coerce
> Prelude Unsafe.Coerce> data P = P Int Double deriving Show
> Prelude Unsafe.Coerce> data Q a b = Q a b deriving Show
> Prelude Unsafe.Coerce> unsafeCoerce (P 23 2.33) :: Q Int Double
> Q 23 2.33

And it works even for sum type, and the first constructor always wins.

> Prelude Unsafe.Coerce> data M a = J a deriving Show
> Prelude Unsafe.Coerce> unsafeCoerce (J "qwe") :: Either String String
> Left "qwe"
> Prelude Unsafe.Coerce> unsafeCoerce (Just "qwe") :: M String
> J "qwe"

And the documenation for unsafeCoerce# says

> Casting between two types that have the same runtime representation. One case is when the two types differ only in "phantom" type parameters, for example Ptr Int to Ptr Float, or [Int] to [Float] when the list is known to be empty. Also, a newtype of a type T has the same representation at runtime as T.
> http://hackage.haskell.org/package/base-

But info tables for different constructors are different. Why does the
code above work?

And is it safe to use unsafeCoerce like this?

Cosmia Fu

More information about the Haskell-Cafe mailing list