module Main (main) where import Control.Monad (liftM) import Control.Monad.Trans (lift) import Control.Monad.State (StateT, evalStateT, State, evalState, get, put) main :: IO () main = do xs <- readFile "data" ys <- readFile "data" print (evalState readChunks xs == ys) --- type InnerMonad = State String readChunks :: InnerMonad String readChunks = do xs <- get if null xs then return [] else do ys <- foo get put rest <- readChunks return (ys ++ rest) --- data St m = St { get_inp :: m String, put_inp :: String -> m () } type OuterMonad m = StateT (St m) m foo :: Monad m => m String -> (String -> m ()) -> m String foo getter putter = evalStateT bar (St getter putter) bar :: Monad m => OuterMonad m String bar = do st <- get inp <- lift $ get_inp st case inp of [] -> return [] x:xs -> do lift $ put_inp st xs liftM (x:) bar