> {-# notInline test #-}
> test :: IORef [a]
> test = unsafePerformIO $ newIORef []
> 
> main = do
>     writeIORef test [42]
>     bang <- readIORef test
>     print (bang :: [Char])

This is a very well-known problem in the ML community.
In the original monadic I/O paper (POPL'93), Phil and I mentioned
it and briefly discussed why it doesn't arise in monadic I/O.
But that was before unsafePerformIO!   

The ML people now have the "value restriction" to ensure this
doesn't happen: let-bound polymorphism is restricted to values.

I don't know any way to make unsafePerformIO type-safe without imposing
some drastic or complicated restriction.  Something in the back of
my mind tells me that John Launchbury has another example of
type unsafety induced by unsafePerformIO but I can't remember what;
so I'm cc'ing him.

Either way, we should document the issue.  It is certainly not
an *obvious* problem with unsafePerformIO.  Did you come across it
in anger?

Simon

Reply via email to