Help: Haskell async behavior I don't understand

You can do that like this:

raceAnySuccess xs = do
  nref <- newIORef (length xs)
  let
    h :: SomeException -> IO a
    h e = do
      n <- atomicModifyIORef' nref (\n -> (n - 1, n - 1))
      if n == 0 then error "All threads failed" else forever
  runConcurrently $ asum $
    map
      (\x -> Concurrently $
        x `catches` [ Handler (\(e :: AsyncCancelled) -> throwIO e)
                    , Handler h ])
      xs

Instead of catching and rethrowing AsyncCancelled you can also just only catch the particular errors you’re interested in, if you know your domain.

By the way, you might see even better results if you use Conc from unliftio. Edit: I tried this and it also seems to be very slow.