-- | Waiting (for replies).
module Sound.OSC.Wait where

import System.Timeout {- base -}

-- * Timeout

-- | Variant of 'timeout' where time is given in fractional seconds.
timeout_r :: Double -> IO a -> IO (Maybe a)
timeout_r :: Double -> IO a -> IO (Maybe a)
timeout_r = Int -> IO a -> IO (Maybe a)
forall a. Int -> IO a -> IO (Maybe a)
timeout (Int -> IO a -> IO (Maybe a))
-> (Double -> Int) -> Double -> IO a -> IO (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor (Double -> Int) -> (Double -> Double) -> Double -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000000)

-- * Wait

-- | Repeat action until predicate /f/ is 'True' when applied to result.
untilPredicate :: Monad m => (a -> Bool) -> m a -> m a
untilPredicate :: (a -> Bool) -> m a -> m a
untilPredicate a -> Bool
f m a
act =
    let g :: a -> m a
g a
p = if a -> Bool
f a
p then m a
recur else a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
p
        recur :: m a
recur = m a
act m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m a
g
    in m a
recur

-- | Repeat action until /f/ does not give 'Nothing' when applied to result.
untilMaybe :: Monad m => (a -> Maybe b) -> m a -> m b
untilMaybe :: (a -> Maybe b) -> m a -> m b
untilMaybe a -> Maybe b
f m a
act =
    let g :: a -> m b
g a
p = m b -> (b -> m b) -> Maybe b -> m b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m b
recur b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Maybe b
f a
p)
        recur :: m b
recur = m a
act m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m b
g
    in m b
recur