# 29 IO

One interesting thing about how IO is defined is that

newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))

is that it inverts the usual perspective of subjective thought happening within an objective world. IO is like looking into the universe from the plane of pure Platonic computation, calculating its physics forward a step in time, and then plucking out the type a you happen to want. It’s a very heady perspective, and small wonder people get hooked on it.

But it’s important to remember that this perspective is a lie. GHC is only simulating the outside-view; the code we run is still very much within the universe and generating causal effects like heating our cpu, increasing our electric bill etc. etc. These effects are usually (but not always) small, which is what makes the simulated outside perspective useful.

The outside perspective preserves purity by modeling (or pretending to model) the whole universe as a pure function. The IO type is that model, it makes GHC safely switch off simulating computation as something that happens outside of time and space. Within IO, GHC respects RealWorld time, and doesn’t mess with our execution order.

There is also an unsafe way to punch a hole in the simulation:

import System.IO.Unsafe

unsafe :: Int
unsafe = unsafePerformIO (print "a hole in the simulation" >> return 2)

main :: IO ()
main = do
putStrLn "the outside perspective"
print \$ 2 + unsafe

## 29.9 Chapter Exercises

### File IO with Vigenere

see src/VignereFile.hs

### Config directories

see src/ConfigDirectories.hs

I love how terse this program is. Just traverse a parser and zip!