I often find useful a generalized version of Concurrently that wraps a IO (Either e a) instead of a IO a, and for which the Applicative behaves like a mix of race and concurrently: if one of the actions returns a Left, cancel the other one and immediately return the Left. If both actions return a Right, behave similarly to Concurrently.
The alternative is to simply use Concurrently and throw and catch exceptions, but I've found that solution less ergonomic (when the "error" e is some interesting type, you have to declare a special-purpose exception in order to hold it).
A type similar to ConcurrentlyE is already provided by the conceit package.
I often find useful a generalized version of
Concurrently
that wraps aIO (Either e a)
instead of aIO a
, and for which theApplicative
behaves like a mix ofrace
andconcurrently
: if one of the actions returns aLeft
, cancel the other one and immediately return theLeft
. If both actions return aRight
, behave similarly toConcurrently
.The alternative is to simply use
Concurrently
and throw and catch exceptions, but I've found that solution less ergonomic (when the "error"e
is some interesting type, you have to declare a special-purpose exception in order to hold it).A type similar to
ConcurrentlyE
is already provided by the conceit package.