module Control.Monad.Fibre (
module Control.Monad.Bi,
(<||>), (<&&>),
) where
import Control.Concurrent (forkIO, newEmptyMVar, takeMVar, putMVar)
import Control.Monad.Bi (MonadBi(..))
(<||>) :: (Monad m, MonadBi m IO) => m o -> m o -> m o
t1 <||> t2 = do
t1io <- lower t1
t2io <- lower t2
x <- raise newEmptyMVar
raise $ do
forkIO $ t1io >>= putMVar x
forkIO $ t2io >>= putMVar x
raise $ takeMVar x
(<&&>) :: (Monad m, MonadBi m IO) => m o1 -> m o2 -> m (o1,o2)
t1 <&&> t2 = do
t1io <- lower t1
t2io <- lower t2
x1 <- raise newEmptyMVar
x2 <- raise newEmptyMVar
raise $ do
forkIO $ t1io >>= putMVar x1
forkIO $ t2io >>= putMVar x2
xv1 <- raise $ takeMVar x1
xv2 <- raise $ takeMVar x2
return (xv1,xv2)