module Utils where
import Control.Concurrent.MVar ( MVar, putMVar, tryTakeMVar )
import Control.Exception ( SomeException(SomeException)
, block, throwIO
)
import Control.Monad ( Monad, return, (>>=), (>>), fail )
import Data.Bool ( Bool )
import Data.Function ( ($), flip )
import Data.Functor ( Functor, (<$>), (<$) )
import Data.Maybe ( Maybe(Nothing, Just) )
import System.IO ( IO )
(<$$>) ∷ Functor f ⇒ f α → (α → β) → f β
(<$$>) = flip (<$>)
void ∷ Functor f ⇒ f α → f ()
void = (() <$)
ifM ∷ Monad m ⇒ m Bool → m α → m α → m α
ifM c t e = c >>= \b → if b then t else e
whenThen ∷ Monad m ⇒ Bool → m () → m α → m α
whenThen b t a = if b then t >> a else a
throwInner ∷ SomeException → IO α
throwInner (SomeException e) = throwIO e
tryRead ∷ MVar α → IO (Maybe α)
tryRead mv = block $ do mx ← tryTakeMVar mv
case mx of
Nothing → return mx
Just x → putMVar mv x >> return mx