
Yes, it is entirely possible to do this, and in fact we used to have such a thing (withStdout, withStderr) which got dropped when I re-implemented the I/O system. It's not immediately clear what the interface should be, though. If we have
setStdout :: Handle -> IO ()
what happens to the original handle?
A pattern common in the Win32 GDI is to use a type like: setStdout :: Handle -> IO Handle Which makes it easy to implement things like: withStdout :: Handle -> IO a -> IO a withStdout h m = do h' <- setStdout h m setStdout h' At some point, it might also be useful to introduce a notion of processes to GHC in addition to its current notion of threads. What I mean by this is: - with threads, you have independent execution of code but all threads see the same global environment. That is, stdout is the same for all of them. - with processes, you have independent execution but each process sees a different global environment. That is, processes can have different notions of stdout. Perhaps this is best done using implicit parameters though? We could bundle up all those environmental things (getArgs, stdout, etc.) in a record and pass it around... -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/