module Data.Iteratee.IO.Interact ( ioIter ) where import Control.Monad.IO.Class import Data.Iteratee -- | Use an IO function to choose what iteratee to run. -- -- Typically this function handles user interaction and -- -- returns with a simple iteratee such as 'head' or 'seek'. -- -- -- -- The IO function takes a value of type 'a' as input, and -- -- should return 'Right a' to continue, or 'Left b' -- -- to terminate. Upon termination, ioIter will return 'Done b'. -- -- -- -- The second argument to 'ioIter' is used as the initial input -- -- to the IO function, and on each successive iteration the -- -- previously returned value is used as input. Put another way, -- -- the value of type 'a' is used like a fold accumulator. -- -- The value of type 'b' is typically some form of control code -- -- that the application uses to signal the reason for termination. ioIter :: (MonadIO m, Nullable s) => (a -> IO (Either b (Iteratee s m a))) -> a -> Iteratee s m b ioIter f a = either return (>>= ioIter f) =<< liftIO (f a) {-# INLINE ioIter #-}