Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`unsafeCoerce` implementation in Haskell

Tags:

haskell

ghc

I have heard that various type system hacks in Haskell (unsafePerformIO, Template Haskell, arbitrary-rank polymorphism,...) can be used to coerce different types, but I haven't seen the explicit implementations. How is it done, at least in GHC?

like image 593
ThePiercingPrince Avatar asked Mar 01 '14 13:03

ThePiercingPrince


1 Answers

On unsafePerformIO

You can use unsafePerformIO to create top-level IORefs, i.e. mutable global variables. If you add polymorphism to this, you lose type safety as follows:

myVar :: IORef a -- polymorphic ref!
myVar = unsafePerformIO $ newIORef undefined

coerce :: a -> b
coerce x = unsafePerformIO $ do
    writeIORef myVar x  -- write value of type a
    readIORef myVar     -- read value of type b

Basically, a (non bottom) value of type forall a. IORef a should not exist, ever. Its type states that you can use it as a mutable variable of the type you want, so you can write to it pretending it has one type, and then read from it pretending it has another type.

Note that monomorphic top-level IORefs do not lead to type unsafety, since you can only write and read those at the same type.

On others

Higher ranks are type safe, AFAIK.

I also do not know about Template Haskell.

Another source of type unsafety is user-written Typeable instances, since those allow you to claim your own new datatype is actually an Int and successfully use cast to coerce values.

like image 95
chi Avatar answered Oct 03 '22 21:10

chi