I want something that looks like a file Handle but is really backed by an in-memory buffer to use for IO redirects. How can I do this?
I don't know. But I'm pretty sure you could get a near-instantaneous answer for this in #haskell
on irc.freenode.net
. (Not that Stack Overflow isn't nice... You should post the answer back here so Google will find it someday.)
This may not be possible. GHC, at least, seems to require a Handle to have an OS file descriptor that is used for all read/write/seek operations.
See /libraries/base/IOBase.lhs
from the GHC sources.
You may be able to get the same effect by enlisting the OS's help: create a temporary file, connect the Handle to it and then memory map the file for the IO redirects. This way, all the handle IO would become visible in the memory mapped section.
It's not possible without modifying the compiler. This is because Handle is an abstract data type, not a typeclass.
If you can express what you want to do in terms of C or system calls you could use Haskell's Foreign Function Interface (FFI). I started to suggest using mmap, but on second thought I think mmap might be a mapping the wrong way even if you used it with the anonymous option.
You can find more information about the Haskell FFI at the haskell.org wiki.
This is actually a bug in the library design, and one that's annoyed me, too. I see two approaches to doing what you want, neither of which is terribly attractive.
Create a new typeclass, make the current Handle an instance of it, write another instance to do the in-memory-data thing, and change all of your programs that need to use this facility. Possibly this is as simple as importing System.SIO (or whatever you want to call it) instead of System.IO. But if you use the custom IO routines in libraries such as Data.ByteString, there's more work to be done there.
Rewrite the IO libraries to extend them to support this. Not trivial, and a lot of work, but it wouldn't be particularly difficult work to do. However, then you've got a compatability issue with systems that don't have this library.