Perhaps this is what you are looking for?
main = print =<< fmap (`evalState` 0) (go get) where go :: State Int Int -> IO (State Int Int) go st = do l <- getLine if null l then return (st >>= \_ -> get) else do let ln = evalState st 0 putStrLn(show ln ++ ' ' : reverse l) go (st >>= \_ -> modify (+1) >>= \_ -> get)
The idea here is to make a recursive go tail, creating a state calculation that you can then evaluate at each step.
EDIT
This version will tie the size of the state calculation to a constant size, although with lazy evaluation, when the previous state calculation is mandatory, we should be able to reuse it without re-evaluation, so I assume that they are essentially the same ...
main = print =<< fmap (`evalState` 0) (go get) where go :: State Int Int -> IO (State Int Int) go st = do l <- getLine if null l then return st else do let ln = evalState st 0 putStrLn(show ln ++ ' ' : reverse l) go (modify (\s -> s+ln+1) >>= \_ -> get)
source share