    {-# LANGUAGE DeriveFunctor #-}

    -- | A bit like 'Fence', but not thread safe and optimised for avoiding taking the fence
    module General.Wait(
        Wait(Now,Later), runWait, quickly, fromLater,
        firstJustWaitUnordered, firstLeftWaitUnordered
        ) where

    import Control.Monad.Extra
    import Control.Monad.IO.Class
    import Data.IORef.Extra
    import Data.List.Extra
    import Data.Primitive.Array
    import GHC.Exts(RealWorld)
    import Control.Monad.Fail
    import Prelude

    runWait :: Monad m => Wait m a -> m (Wait m a)
    runWait :: Wait m a -> m (Wait m a)
    runWait (Lift x :: m (Wait m a)
    x) = Wait m a -> m (Wait m a)
    forall (m :: * -> *) a. Monad m => Wait m a -> m (Wait m a)
    runWait (Wait m a -> m (Wait m a)) -> m (Wait m a) -> m (Wait m a)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< m (Wait m a)
    x
    runWait x :: Wait m a
    x = Wait m a -> m (Wait m a)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Wait m a
    x

    fromLater :: Monad m => Wait m a -> (a -> m ()) -> m ()
    fromLater :: Wait m a -> (a -> m ()) -> m ()
    fromLater (Lift x :: m (Wait m a)
    x) f :: a -> m ()
    f = do Wait m a
    x <- m (Wait m a)
    x; Wait m a -> (a -> m ()) -> m ()
    forall (m :: * -> *) a. Monad m => Wait m a -> (a -> m ()) -> m ()
    fromLater Wait m a
    x a -> m ()
    f
    fromLater (Now x :: a
    x) f :: a -> m ()
    f = a -> m ()
    f a
    x
    fromLater (Later x :: (a -> m ()) -> m ()
    x) f :: a -> m ()
    f = (a -> m ()) -> m ()
    x a -> m ()
    f

    quickly :: Functor m => m a -> Wait m a
    quickly :: m a -> Wait m a
    quickly = m (Wait m a) -> Wait m a
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m a) -> Wait m a)
    -> (m a -> m (Wait m a)) -> m a -> Wait m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Wait m a) -> m a -> m (Wait m a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> Wait m a
    forall (m :: * -> *) a. a -> Wait m a
    Now

    data Wait m a = Now a
                  | Lift (m (Wait m a))
                  | Later ((a -> m ()) -> m ())
                    deriving a -> Wait m b -> Wait m a
    (a -> b) -> Wait m a -> Wait m b
    (forall a b. (a -> b) -> Wait m a -> Wait m b)
    -> (forall a b. a -> Wait m b -> Wait m a) -> Functor (Wait m)
    forall a b. a -> Wait m b -> Wait m a
    forall a b. (a -> b) -> Wait m a -> Wait m b
    forall (m :: * -> *) a b. Functor m => a -> Wait m b -> Wait m a
    forall (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> Wait m a -> Wait m b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    <$ :: a -> Wait m b -> Wait m a
    $c<$ :: forall (m :: * -> *) a b. Functor m => a -> Wait m b -> Wait m a
    fmap :: (a -> b) -> Wait m a -> Wait m b
    $cfmap :: forall (m :: * -> *) a b.
    Functor m =>
    (a -> b) -> Wait m a -> Wait m b
    Functor

    instance (Monad m, Applicative m) => Applicative (Wait m) where
        pure :: a -> Wait m a
    pure = a -> Wait m a
    forall (m :: * -> *) a. a -> Wait m a
    Now
        Now x :: a -> b
    x <*> :: Wait m (a -> b) -> Wait m a -> Wait m b
    <*> y :: Wait m a
    y = a -> b
    x (a -> b) -> Wait m a -> Wait m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Wait m a
    y
        Lift x :: m (Wait m (a -> b))
    x <*> y :: Wait m a
    y = m (Wait m b) -> Wait m b
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m b) -> Wait m b) -> m (Wait m b) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ (Wait m (a -> b) -> Wait m a -> Wait m b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Wait m a
    y) (Wait m (a -> b) -> Wait m b)
    -> m (Wait m (a -> b)) -> m (Wait m b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m (Wait m (a -> b))
    x
        Later x :: ((a -> b) -> m ()) -> m ()
    x <*> Now y :: a
    y = ((b -> m ()) -> m ()) -> Wait m b
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (((b -> m ()) -> m ()) -> Wait m b)
    -> ((b -> m ()) -> m ()) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ \c :: b -> m ()
    c -> ((a -> b) -> m ()) -> m ()
    x (((a -> b) -> m ()) -> m ()) -> ((a -> b) -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \x :: a -> b
    x -> b -> m ()
    c (b -> m ()) -> b -> m ()
    forall a b. (a -> b) -> a -> b
    $ a -> b
    x a
    y
        -- Note: We pull the Lift from the right BEFORE the Later, to enable parallelism
        Later x :: ((a -> b) -> m ()) -> m ()
    x <*> Lift y :: m (Wait m a)
    y = m (Wait m b) -> Wait m b
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m b) -> Wait m b) -> m (Wait m b) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ do Wait m a
    y <- m (Wait m a)
    y; Wait m b -> m (Wait m b)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Wait m b -> m (Wait m b)) -> Wait m b -> m (Wait m b)
    forall a b. (a -> b) -> a -> b
    $ (((a -> b) -> m ()) -> m ()) -> Wait m (a -> b)
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later ((a -> b) -> m ()) -> m ()
    x Wait m (a -> b) -> Wait m a -> Wait m b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Wait m a
    y
        Later x :: ((a -> b) -> m ()) -> m ()
    x <*> Later y :: (a -> m ()) -> m ()
    y = ((b -> m ()) -> m ()) -> Wait m b
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (((b -> m ()) -> m ()) -> Wait m b)
    -> ((b -> m ()) -> m ()) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ \c :: b -> m ()
    c -> ((a -> b) -> m ()) -> m ()
    x (((a -> b) -> m ()) -> m ()) -> ((a -> b) -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \x :: a -> b
    x -> (a -> m ()) -> m ()
    y ((a -> m ()) -> m ()) -> (a -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \y :: a
    y -> b -> m ()
    c (b -> m ()) -> b -> m ()
    forall a b. (a -> b) -> a -> b
    $ a -> b
    x a
    y

    instance (Monad m, Applicative m) => Monad (Wait m) where
        return :: a -> Wait m a
    return = a -> Wait m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
        >> :: Wait m a -> Wait m b -> Wait m b
    (>>) = Wait m a -> Wait m b -> Wait m b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    (*>)
        Now x :: a
    x >>= :: Wait m a -> (a -> Wait m b) -> Wait m b
    >>= f :: a -> Wait m b
    f = a -> Wait m b
    f a
    x
        Lift x :: m (Wait m a)
    x >>= f :: a -> Wait m b
    f = m (Wait m b) -> Wait m b
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m b) -> Wait m b) -> m (Wait m b) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ do Wait m a
    x <- m (Wait m a)
    x; Wait m b -> m (Wait m b)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Wait m b -> m (Wait m b)) -> Wait m b -> m (Wait m b)
    forall a b. (a -> b) -> a -> b
    $ Wait m a
    x Wait m a -> (a -> Wait m b) -> Wait m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> Wait m b
    f
        Later x :: (a -> m ()) -> m ()
    x >>= f :: a -> Wait m b
    f = ((b -> m ()) -> m ()) -> Wait m b
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (((b -> m ()) -> m ()) -> Wait m b)
    -> ((b -> m ()) -> m ()) -> Wait m b
    forall a b. (a -> b) -> a -> b
    $ \c :: b -> m ()
    c -> (a -> m ()) -> m ()
    x ((a -> m ()) -> m ()) -> (a -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \x :: a
    x -> do
            Wait m b
    x <- Wait m b -> m (Wait m b)
    forall (m :: * -> *) a. Monad m => Wait m a -> m (Wait m a)
    runWait (Wait m b -> m (Wait m b)) -> Wait m b -> m (Wait m b)
    forall a b. (a -> b) -> a -> b
    $ a -> Wait m b
    f a
    x
            case Wait m b
    x of
                Now x :: b
    x -> b -> m ()
    c b
    x
                _ -> Wait m b -> (b -> m ()) -> m ()
    forall (m :: * -> *) a. Monad m => Wait m a -> (a -> m ()) -> m ()
    fromLater Wait m b
    x b -> m ()
    c

    instance (MonadIO m,  Applicative m) => MonadIO (Wait m) where
        liftIO :: IO a -> Wait m a
    liftIO = m (Wait m a) -> Wait m a
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m a) -> Wait m a)
    -> (IO a -> m (Wait m a)) -> IO a -> Wait m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO (Wait m a) -> m (Wait m a)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Wait m a) -> m (Wait m a))
    -> (IO a -> IO (Wait m a)) -> IO a -> m (Wait m a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Wait m a) -> IO a -> IO (Wait m a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> Wait m a
    forall (m :: * -> *) a. a -> Wait m a
    Now

    instance MonadFail m => MonadFail (Wait m) where
        fail :: String -> Wait m a
    fail = m (Wait m a) -> Wait m a
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m a) -> Wait m a)
    -> (String -> m (Wait m a)) -> String -> Wait m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> m (Wait m a)
    forall (m :: * -> *) a. MonadFail m => String -> m a
    Control.Monad.Fail.fail

    firstJustWaitUnordered :: MonadIO m => (a -> Wait m (Maybe b)) -> [a] -> Wait m (Maybe b)
    firstJustWaitUnordered :: (a -> Wait m (Maybe b)) -> [a] -> Wait m (Maybe b)
    firstJustWaitUnordered f :: a -> Wait m (Maybe b)
    f = [(Maybe b -> m ()) -> m ()]
    -> [Wait m (Maybe b)] -> Wait m (Maybe b)
    forall (m :: * -> *) a.
    MonadIO m =>
    [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    go [] ([Wait m (Maybe b)] -> Wait m (Maybe b))
    -> ([a] -> [Wait m (Maybe b)]) -> [a] -> Wait m (Maybe b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Wait m (Maybe b)) -> [a] -> [Wait m (Maybe b)]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Wait m (Maybe b)
    f
        where
            -- keep a list of those things we might visit later, and ask for each we see in turn
            go :: MonadIO m => [(Maybe a -> m ()) -> m ()] -> [Wait m (Maybe a)] -> Wait m (Maybe a)
            go :: [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    go later :: [(Maybe a -> m ()) -> m ()]
    later (x :: Wait m (Maybe a)
    x:xs :: [Wait m (Maybe a)]
    xs) = case Wait m (Maybe a)
    x of
                Now (Just a :: a
    a) -> Maybe a -> Wait m (Maybe a)
    forall (m :: * -> *) a. a -> Wait m a
    Now (Maybe a -> Wait m (Maybe a)) -> Maybe a -> Wait m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
                Now Nothing -> [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    forall (m :: * -> *) a.
    MonadIO m =>
    [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    go [(Maybe a -> m ()) -> m ()]
    later [Wait m (Maybe a)]
    xs
                Later l :: (Maybe a -> m ()) -> m ()
    l -> [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    forall (m :: * -> *) a.
    MonadIO m =>
    [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    go ((Maybe a -> m ()) -> m ()
    l((Maybe a -> m ()) -> m ())
    -> [(Maybe a -> m ()) -> m ()] -> [(Maybe a -> m ()) -> m ()]
    forall a. a -> [a] -> [a]
    :[(Maybe a -> m ()) -> m ()]
    later) [Wait m (Maybe a)]
    xs
                Lift x :: m (Wait m (Maybe a))
    x -> m (Wait m (Maybe a)) -> Wait m (Maybe a)
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m (Maybe a)) -> Wait m (Maybe a))
    -> m (Wait m (Maybe a)) -> Wait m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ do
                    Wait m (Maybe a)
    x <- m (Wait m (Maybe a))
    x
                    Wait m (Maybe a) -> m (Wait m (Maybe a))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Wait m (Maybe a) -> m (Wait m (Maybe a)))
    -> Wait m (Maybe a) -> m (Wait m (Maybe a))
    forall a b. (a -> b) -> a -> b
    $ [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    forall (m :: * -> *) a.
    MonadIO m =>
    [(Maybe a -> m ()) -> m ()]
    -> [Wait m (Maybe a)] -> Wait m (Maybe a)
    go [(Maybe a -> m ()) -> m ()]
    later (Wait m (Maybe a)
    xWait m (Maybe a) -> [Wait m (Maybe a)] -> [Wait m (Maybe a)]
    forall a. a -> [a] -> [a]
    :[Wait m (Maybe a)]
    xs)
            go [] [] = Maybe a -> Wait m (Maybe a)
    forall (m :: * -> *) a. a -> Wait m a
    Now Maybe a
    forall a. Maybe a
    Nothing
            go [l :: (Maybe a -> m ()) -> m ()
    l] [] = ((Maybe a -> m ()) -> m ()) -> Wait m (Maybe a)
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (Maybe a -> m ()) -> m ()
    l
            go ls :: [(Maybe a -> m ()) -> m ()]
    ls [] = ((Maybe a -> m ()) -> m ()) -> Wait m (Maybe a)
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (((Maybe a -> m ()) -> m ()) -> Wait m (Maybe a))
    -> ((Maybe a -> m ()) -> m ()) -> Wait m (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ \callback :: Maybe a -> m ()
    callback -> do
                IORef Int
    ref <- IO (IORef Int) -> m (IORef Int)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (IORef Int) -> m (IORef Int))
    -> IO (IORef Int) -> m (IORef Int)
    forall a b. (a -> b) -> a -> b
    $ Int -> IO (IORef Int)
    forall a. a -> IO (IORef a)
    newIORef (Int -> IO (IORef Int)) -> Int -> IO (IORef Int)
    forall a b. (a -> b) -> a -> b
    $ [(Maybe a -> m ()) -> m ()] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Maybe a -> m ()) -> m ()]
    ls
                [(Maybe a -> m ()) -> m ()]
    -> (((Maybe a -> m ()) -> m ()) -> m ()) -> m ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ [(Maybe a -> m ()) -> m ()]
    ls ((((Maybe a -> m ()) -> m ()) -> m ()) -> m ())
    -> (((Maybe a -> m ()) -> m ()) -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \l :: (Maybe a -> m ()) -> m ()
    l -> (Maybe a -> m ()) -> m ()
    l ((Maybe a -> m ()) -> m ()) -> (Maybe a -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \r :: Maybe a
    r -> do
                    Int
    old <- IO Int -> m Int
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Int -> m Int) -> IO Int -> m Int
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> IO Int
    forall a. IORef a -> IO a
    readIORef IORef Int
    ref
                    Bool -> m () -> m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    old Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0) (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $ case Maybe a
    r of
                        Just a :: a
    a -> do
                            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> Int -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef' IORef Int
    ref 0
                            Maybe a -> m ()
    callback (Maybe a -> m ()) -> Maybe a -> m ()
    forall a b. (a -> b) -> a -> b
    $ a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
                        Nothing -> do
                            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> Int -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef' IORef Int
    ref (Int -> IO ()) -> Int -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Int
    oldInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1
                            Bool -> m () -> m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    old Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 1) (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Maybe a -> m ()
    callback Maybe a
    forall a. Maybe a
    Nothing

    firstLeftWaitUnordered :: MonadIO m => (a -> Wait m (Either e b)) -> [a] -> Wait m (Either e [b])
    firstLeftWaitUnordered :: (a -> Wait m (Either e b)) -> [a] -> Wait m (Either e [b])
    firstLeftWaitUnordered f :: a -> Wait m (Either e b)
    f xs :: [a]
    xs = do
            let n :: Int
    n = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    xs
            MutableArray RealWorld b
    mut <- IO (MutableArray RealWorld b) -> Wait m (MutableArray RealWorld b)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (MutableArray RealWorld b)
     -> Wait m (MutableArray RealWorld b))
    -> IO (MutableArray RealWorld b)
    -> Wait m (MutableArray RealWorld b)
    forall a b. (a -> b) -> a -> b
    $ Int -> b -> IO (MutableArray (PrimState IO) b)
    forall (m :: * -> *) a.
    PrimMonad m =>
    Int -> a -> m (MutableArray (PrimState m) a)
    newArray Int
    n b
    forall a. HasCallStack => a
    undefined
            Maybe e
    res <- MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    forall (m :: * -> *) b e.
    MonadIO m =>
    MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    go MutableArray RealWorld b
    mut [] ([(Int, Wait m (Either e b))] -> Wait m (Maybe e))
    -> [(Int, Wait m (Either e b))] -> Wait m (Maybe e)
    forall a b. (a -> b) -> a -> b
    $ Int -> [Wait m (Either e b)] -> [(Int, Wait m (Either e b))]
    forall a b. Enum a => a -> [b] -> [(a, b)]
    zipFrom 0 ([Wait m (Either e b)] -> [(Int, Wait m (Either e b))])
    -> [Wait m (Either e b)] -> [(Int, Wait m (Either e b))]
    forall a b. (a -> b) -> a -> b
    $ (a -> Wait m (Either e b)) -> [a] -> [Wait m (Either e b)]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Wait m (Either e b)
    f [a]
    xs
            case Maybe e
    res of
                Just e :: e
    e -> Either e [b] -> Wait m (Either e [b])
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Either e [b] -> Wait m (Either e [b]))
    -> Either e [b] -> Wait m (Either e [b])
    forall a b. (a -> b) -> a -> b
    $ e -> Either e [b]
    forall a b. a -> Either a b
    Left e
    e
                Nothing -> IO (Either e [b]) -> Wait m (Either e [b])
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Either e [b]) -> Wait m (Either e [b]))
    -> IO (Either e [b]) -> Wait m (Either e [b])
    forall a b. (a -> b) -> a -> b
    $ [b] -> Either e [b]
    forall a b. b -> Either a b
    Right ([b] -> Either e [b]) -> IO [b] -> IO (Either e [b])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> IO b) -> [Int] -> IO [b]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (MutableArray (PrimState IO) b -> Int -> IO b
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutableArray (PrimState m) a -> Int -> m a
    readArray MutableArray RealWorld b
    MutableArray (PrimState IO) b
    mut) [0..Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1]
        where
            -- keep a list of those things we might visit later, and ask for each we see in turn
            go :: MonadIO m => MutableArray RealWorld b -> [(Int, (Either e b -> m ()) -> m ())] -> [(Int, Wait m (Either e b))] -> Wait m (Maybe e)
            go :: MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    go mut :: MutableArray RealWorld b
    mut later :: [(Int, (Either e b -> m ()) -> m ())]
    later ((i :: Int
    i,x :: Wait m (Either e b)
    x):xs :: [(Int, Wait m (Either e b))]
    xs) = case Wait m (Either e b)
    x of
                Now (Left e :: e
    e) -> Maybe e -> Wait m (Maybe e)
    forall (m :: * -> *) a. a -> Wait m a
    Now (Maybe e -> Wait m (Maybe e)) -> Maybe e -> Wait m (Maybe e)
    forall a b. (a -> b) -> a -> b
    $ e -> Maybe e
    forall a. a -> Maybe a
    Just e
    e
                Now (Right b :: b
    b) -> do
                    IO () -> Wait m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> Wait m ()) -> IO () -> Wait m ()
    forall a b. (a -> b) -> a -> b
    $ MutableArray (PrimState IO) b -> Int -> b -> IO ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutableArray (PrimState m) a -> Int -> a -> m ()
    writeArray MutableArray RealWorld b
    MutableArray (PrimState IO) b
    mut Int
    i b
    b
                    MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    forall (m :: * -> *) b e.
    MonadIO m =>
    MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    go MutableArray RealWorld b
    mut [(Int, (Either e b -> m ()) -> m ())]
    later [(Int, Wait m (Either e b))]
    xs
                Later l :: (Either e b -> m ()) -> m ()
    l -> MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    forall (m :: * -> *) b e.
    MonadIO m =>
    MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    go MutableArray RealWorld b
    mut ((Int
    i,(Either e b -> m ()) -> m ()
    l)(Int, (Either e b -> m ()) -> m ())
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, (Either e b -> m ()) -> m ())]
    forall a. a -> [a] -> [a]
    :[(Int, (Either e b -> m ()) -> m ())]
    later) [(Int, Wait m (Either e b))]
    xs
                Lift x :: m (Wait m (Either e b))
    x -> m (Wait m (Maybe e)) -> Wait m (Maybe e)
    forall (m :: * -> *) a. m (Wait m a) -> Wait m a
    Lift (m (Wait m (Maybe e)) -> Wait m (Maybe e))
    -> m (Wait m (Maybe e)) -> Wait m (Maybe e)
    forall a b. (a -> b) -> a -> b
    $ do
                    Wait m (Either e b)
    x <- m (Wait m (Either e b))
    x
                    Wait m (Maybe e) -> m (Wait m (Maybe e))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Wait m (Maybe e) -> m (Wait m (Maybe e)))
    -> Wait m (Maybe e) -> m (Wait m (Maybe e))
    forall a b. (a -> b) -> a -> b
    $ MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    forall (m :: * -> *) b e.
    MonadIO m =>
    MutableArray RealWorld b
    -> [(Int, (Either e b -> m ()) -> m ())]
    -> [(Int, Wait m (Either e b))]
    -> Wait m (Maybe e)
    go MutableArray RealWorld b
    mut [(Int, (Either e b -> m ()) -> m ())]
    later ((Int
    i,Wait m (Either e b)
    x)(Int, Wait m (Either e b))
    -> [(Int, Wait m (Either e b))] -> [(Int, Wait m (Either e b))]
    forall a. a -> [a] -> [a]
    :[(Int, Wait m (Either e b))]
    xs)
            go _ [] [] = Maybe e -> Wait m (Maybe e)
    forall (m :: * -> *) a. a -> Wait m a
    Now Maybe e
    forall a. Maybe a
    Nothing
            go mut :: MutableArray RealWorld b
    mut ls :: [(Int, (Either e b -> m ()) -> m ())]
    ls [] = ((Maybe e -> m ()) -> m ()) -> Wait m (Maybe e)
    forall (m :: * -> *) a. ((a -> m ()) -> m ()) -> Wait m a
    Later (((Maybe e -> m ()) -> m ()) -> Wait m (Maybe e))
    -> ((Maybe e -> m ()) -> m ()) -> Wait m (Maybe e)
    forall a b. (a -> b) -> a -> b
    $ \callback :: Maybe e -> m ()
    callback -> do
                IORef Int
    ref <- IO (IORef Int) -> m (IORef Int)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (IORef Int) -> m (IORef Int))
    -> IO (IORef Int) -> m (IORef Int)
    forall a b. (a -> b) -> a -> b
    $ Int -> IO (IORef Int)
    forall a. a -> IO (IORef a)
    newIORef (Int -> IO (IORef Int)) -> Int -> IO (IORef Int)
    forall a b. (a -> b) -> a -> b
    $ [(Int, (Either e b -> m ()) -> m ())] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Int, (Either e b -> m ()) -> m ())]
    ls
                [(Int, (Either e b -> m ()) -> m ())]
    -> ((Int, (Either e b -> m ()) -> m ()) -> m ()) -> m ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ [(Int, (Either e b -> m ()) -> m ())]
    ls (((Int, (Either e b -> m ()) -> m ()) -> m ()) -> m ())
    -> ((Int, (Either e b -> m ()) -> m ()) -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \(i :: Int
    i,l :: (Either e b -> m ()) -> m ()
    l) -> (Either e b -> m ()) -> m ()
    l ((Either e b -> m ()) -> m ()) -> (Either e b -> m ()) -> m ()
    forall a b. (a -> b) -> a -> b
    $ \r :: Either e b
    r -> do
                    Int
    old <- IO Int -> m Int
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Int -> m Int) -> IO Int -> m Int
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> IO Int
    forall a. IORef a -> IO a
    readIORef IORef Int
    ref
                    Bool -> m () -> m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    old Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 0) (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $ case Either e b
    r of
                        Left a :: e
    a -> do
                            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> Int -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef' IORef Int
    ref 0
                            Maybe e -> m ()
    callback (Maybe e -> m ()) -> Maybe e -> m ()
    forall a b. (a -> b) -> a -> b
    $ e -> Maybe e
    forall a. a -> Maybe a
    Just e
    a
                        Right v :: b
    v -> do
                            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ MutableArray (PrimState IO) b -> Int -> b -> IO ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutableArray (PrimState m) a -> Int -> a -> m ()
    writeArray MutableArray RealWorld b
    MutableArray (PrimState IO) b
    mut Int
    i b
    v
                            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ IORef Int -> Int -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef' IORef Int
    ref (Int -> IO ()) -> Int -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Int
    oldInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1
                            Bool -> m () -> m ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Int
    old Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 1) (m () -> m ()) -> m () -> m ()
    forall a b. (a -> b) -> a -> b
    $ Maybe e -> m ()
    callback Maybe e
    forall a. Maybe a
    Nothing