3 ms·
val x = unsafePerformIO $ readIORef x inc x = unsafePerformIO $ modifyIORef x (1+) >> readIORef x main = do x <- newIORef (10::Int) print
by cia_plant 17y ago
val x = unsafePerformIO $ readIORef x
inc x = unsafePerformIO $ modifyIORef x (1+) >> readIORef x
main = do
x <- newIORef (10::Int)
print $ val x + inc x
The result is 21.
Edit: an explanation. GHC runs on graph reduction, and will do "normal order" reduction in the normal case. + is strict in both arguments, so (val x) will be fully evaluated before (inc x) is evaluated.
If we replace with a lazy operator like (:), then we can get different results. Here is a program which will evaluate the (inc x) first:
main = do
x <- newIORef (10::Int)
print $ reverse $ val x : inc x : []
the expression is not fully evaluated until it is printed, and then it is evaluated in reverse order, so inc x runs before val x. The result is [11,11].
Of course, none of this can be relied on. GHC does a lot of optimizations, and unsafe operations are unsafe.