interactive input-output monad
Not to be confused with the standard IO monad.
data IO i o a = Return a | Input (i -> IO i o a) | Output o (IO i o a)
A value of type IO i o a is really an intensional description of a function of type [i] -> ([o], a).
runIO :: IO i o a -> [i] -> ([o], a) runIO (Return a) _ = x runIO (Input k) (i : is) = runIO (k i) is runIO (Output o m) is = (o : os, a) where ~(os, a) = runIO m