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)
deriving (Functor)
instance Applicative (IO i o) where
pure = Return
(<*>) = ap
instance Monad (IO i o) where
Return a >>= k = k a
Input k' >>= k = Input (\i -> k' i >>= k)
Output o m >>= k = Output o (m >>= k)
(>>) = (*>)
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) _ = a
runIO (Input k) (i : is) = runIO (k i) is
runIO (Output o m) is = (o : os, a)
where ~(os, a) = runIO m