I'm the author of a Haskell library[1] for interfacing with HyperDex[2], a distributed database produced by some folks at Cornell.
The client-side library for HyperDex uses an event loop, and is "thread-safe" to call into as long as you synchronize access to the pointer. This is an awkward area to work with in Haskell-land, as the code I write has to deal with the intersection of the three uglies:
* Foreign function interfaces (and marshalling)
* Mutable resource management (allocating and freeing C-structs)
* Concurrency (synchronizing access to an object)
I've tried a variety of implementations. To speed up testing, I wrote a "fake HyperDex" client and test harness in which I can insert chaotic behaviors to test resilience.[3] While the code isn't as clean as I like right now, it lends itself to the smallest, most compact implementations of what I want. Each HyperDex connection pointer is paired with an event loop which receives requests for calls into HyperDex and processes them. When a response is demanded, the loop begins a busy-wait (will soon be replaced by an epoll/select on an fd) on results from the database. Each asynchronous request is an event loop too - a free floating closure sitting in memory that sends off a message and waits for responses.
GHC's garbage collector will determine when waiting on an MVar or Chan is deadlocked, and keeping everything in a ResourceT monad ensures that the whole system gracefully closes when portions fall out of scope and are unreachable.
The approach has a certain elegance to it. I am curious to hear what other people's thoughts are on such implementations though, because there are naturally performance implications.
[1] https://github.com/aaronfriel/hyhac
[3] http://lpaste.net/101084 - a hodgepodge of code I wrote to test implementations - ill-documented, this is just for personal exploration and testing