
Hello Bulat, sorry, I just completely forgot to write down the answer for your post.
Can this be remedied? Can there be a version of writeFile which is, in a sense, dual to getContents?
this can be solved in other way. here is a program that reads stdin and puts to stdout lines starting with '>' and to stderr the rest. note that our main processing function is pure:
main = do a <- getContents let b = map (processing stdout stderr) (lines a) mapM_ (\(file,line) -> hPutStrLn file line) b
processing file1 file2 line = if ">" `isPrefixOf` line then (file1,line) else (file2,line)
(processing) does grouping, but only a part of it. The task of collecting the writes to the different files is still left to the operating system. Furthermore, this code will have a hard time to extend to a dynamical count of files. I imagined that there might be a way where (processing) already does the grouping work and trashes the order in which things were read in and a lazy write would reconstruct the order by laziness and interleave appropriate write calls. But I now think this is not possible. So any grouping function like group :: Input -> Data.Map Key [Value] trashes the order in which different data was read and there cannot be a reconstruction. Of course, if one uses a different grouping data structure which still keeps track of the order of data arrival, i.e. group :: Input -> Data.Magic.Groupy Key Value reconstruction becomes possible. Indeed, (IO a) can be used as "grouping data structure" by virtue of insert :: Key -> Value -> IO () insert = writeFile and this is too short to merit the boilerplate of an additional purely functional abstract data structure between the grouping and the file writing part. One simply does not gain additional clarity. Regards, apfelmus