The equivalent Haskell program is
import Data.IORef
main :: IO ()
main = do
r <- newIORef []
writeIORef r ["Hello"]
x <- readIORef r
print $ x + 1
return ()
The reference is bound by "r <-", ie a lambda (as this desugars to ">>= \ r ->"), and lambdas are never generalized (even in ocaml).I think that the reason why it works is that because there is no way to let-bind r except with a toplevel unsafePerformIO.