<lambdabot> shachaf says: getLine :: IO String contains a String in the same
way that /bin/ls contains a list of files
There are multiple ways IO could be implemented internally. Here’s a demonstration of one.
MiniIO (below) implements an ADT of arbitrarily chosen primitives that represent I/O operations and a way to combine them. One can create, evaluate and manipulate MiniIO values without causing any side effects to occur. That is what example in Main.hs does. The same applies to real IO values in Haskell: you can create a big list of print "hello"s and later pick which ones to actually execute.