module Data.Boombox.Async where import Control.Concurrent import Data.Boombox.Tape import Data.Foldable import Data.Function -- \ Merge multiple tapes in an asynchronous manner. asyncMergeTapes :: Functor w => [Tape w IO a] -> Tape w IO a asyncMergeTapes ts = Tape $ do v <- newChan let go k t = do (a, w) <- unconsTape t writeChan v (a, w, k) takeMVar k >>= go k for_ ts $ \t -> do k <- newEmptyMVar forkIO $ go k t fix $ \self -> do (a, w, k) <- readChan v return (a, fmap (\cont -> Tape $ do putMVar k $! cont self) w)