
This is only peripherally related, but I also have a lot of list functions that can possibly be an error, but usually processing can continue. So they tend to return [Either Error Result]. I have another function thus: -- A foldr version is not lazy enough and overflows the stack. partition_either [] = ([], []) partition_either (x:xs) = let (ls, rs) = partition_either xs in case x of Left l -> (l:ls, rs) Right r -> (ls, r:rs) I was a little surprised I couldn't find this in the standard library... or maybe it is? Anyway, the trick is logging the errors while incrementally processing the non-errors. Logging them first forces the whole thing. Mixing the logging in with the processing forces the processing to be in IO and is not as nice as having it separate. If the next processing step is also pure, the errors must be propagated. 'map (fmap f)' should do it, as long as the errors are all the same type. It's still not ideal because the logs happen in a bunch at the end, and are still taking up memory meanwhile. The only thing I can think of is the dreaded lazy IO... plain unsafePerformIO wouldn't work because nothing is forcing it. It would be sort of an output version of getContents, but it would have to have some magic to know when a thunk has been evaluated without forcing it. But hey, the debugger does it! And the RTS already happily logs things in the middle of pure computation, so this would just be giving programmers access to it... so it's not *so* crazy :)