Change semantics of withAsync & double performance of race and concurrently

Hi Simon,

This is an attempt to solve #5 by following your suggested approach of changing the semantics of `withAsync` such that if the inner function receives an asynchronous exception it will also be thrown to the forked action. But if it receives a synchronous action the forked action will be killed.

This change in semantics allows for an implementation of `race` and `concurrently` which only needs to fork a single thread (instead of two) which doubles performance.

I'm pretty sure that `concurrently` is correct. I'm less sure about `race` because it uses a complex implementation. Although the test cases I added for `race` seem to indicate it operates correctly.

Let me know what you think.

This patch was co-written with my colleague @asayers.