Lazy counting and printing

Hi, I have written a code like this: import Control.Monad.State countedRecords :: [Int] -> StateT Int IO [Int] countedRecords [] = return [] countedRecords (r:rs) = do modify (+1) rest <- countedRecords rs return $ r:rs printEven :: [Int] -> StateT Int IO () printEven records = do let even = filter (\n -> n `mod` 2 == 0) records lift $ mapM_ (putStrLn . show) even combine :: [Int] -> StateT Int IO () combine records = countedRecords records >>= printEven main = do let numbers = [1..1000000] count <- execStateT (combine numbers) 0 putStrLn $ "Processed " ++ show count ++ " numbers." My intent is that of processing a large collection of records (in this example, integers) doing two things at once: count their total number and print those that satisfy a certain condition. I would like to keep the definitions of the two functions performing such tasks independent. As a result I've used the State monad to hide intermediate counts. Unfortunately the code above breaks laziness, in that records are first completely counted (and stored in memory) and only then filtered and printed. If I redefine main as: main = do let numbers = [1..] .. i.e. I produce an unbounded number of records, I get a stack overflow. Moreover, I don't like the way countedRecords and printEven are defined, because their type signatures are too "broad". I would prefer them to be: countedRecords :: [Int] -> State Int [Int] printEven :: [Int] -> IO () and let "combine" do some sort of lifting into the StateT monad. Is there any way to perform both operations lazily? Thanks
participants (1)
-
Anakim Border