module Control.Concurrent.Chan.Extended
    ( module Control.Concurrent.Chan
    , withMapChan
    ) where

import qualified Control.Concurrent.Async as Async
import           Control.Concurrent.Chan
import           Control.Monad            (forever)

withMapChan :: (a -> b) -> Chan a -> (Chan b -> IO r) -> IO r
withMapChan :: forall a b r. (a -> b) -> Chan a -> (Chan b -> IO r) -> IO r
withMapChan a -> b
f Chan a
chan Chan b -> IO r
cont = do
    Chan b
new <- IO (Chan b)
forall a. IO (Chan a)
newChan
    IO Any -> (Async Any -> IO r) -> IO r
forall a b. IO a -> (Async a -> IO b) -> IO b
Async.withAsync
        (IO () -> IO Any
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (IO () -> IO Any) -> IO () -> IO Any
forall a b. (a -> b) -> a -> b
$ Chan a -> IO a
forall a. Chan a -> IO a
readChan Chan a
chan IO a -> (a -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Chan b -> b -> IO ()
forall a. Chan a -> a -> IO ()
writeChan Chan b
new (b -> IO ()) -> (a -> b) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)
        (\Async Any
_ -> Chan b -> IO r
cont Chan b
new)