1. Totally, definitely. The new Haskell IO manager in GHC 7.8 completely blows this out of the water. It's wonderful.
2. You fork or async IO procedures which can be considered immutable values in their own right and passed around without the slightest concern. There is a small difficulty in that Haskell's laziness makes it a small trick to ensure that work gets done in the right place, which is undoubtedly a mark against Haskell, though perhaps not a huge one.
3. Things like STM, MVars, and (now) LVish let this happen in all kinds of ways. The only problem might be picking the right option due to the wealth of choices. Fortunately, the right answer is almost always STM.
I'd be more than happy to translate a task to demonstrate these things.