    {-# LANGUAGE CPP #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE FlexibleContexts #-}

    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Safe #-}
    #endif

    {- |
    Module      :  Control.Concurrent.Chan.Lifted
    Copyright   :  Liyang HU, Bas van Dijk
    License     :  BSD-style

    Maintainer  :  Bas van Dijk <v.dijk.bas@gmail.com>
    Stability   :  experimental

    This is a wrapped version of "Control.Concurrent.Chan" with types
    generalised from 'IO' to all monads in 'MonadBase'.

    'Chan.unGetChan' and 'Chan.isEmptyChan' are deprecated in @base@, therefore
    they are not included here. Use 'Control.Concurrent.STM.TVar' instead.
    -}

    module Control.Concurrent.Chan.Lifted
        ( Chan
        , newChan
        , writeChan
        , readChan
        , dupChan
        , getChanContents
        , writeList2Chan
        ) where

    --------------------------------------------------------------------------------
    -- Imports
    --------------------------------------------------------------------------------

    -- from base:
    import Control.Concurrent.Chan ( Chan )
    import qualified Control.Concurrent.Chan as Chan
    import System.IO ( IO )
    import Prelude ( (.) )

    -- from transformers-base:
    import Control.Monad.Base ( MonadBase, liftBase )

    #include "inlinable.h"

    --------------------------------------------------------------------------------
    -- * Chans
    --------------------------------------------------------------------------------

    -- | Generalized version of 'Chan.newChan'.
    newChan :: MonadBase IO m => m (Chan a)
    newChan :: m (Chan a)
    newChan = IO (Chan a) -> m (Chan a)
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase IO (Chan a)
    forall a. IO (Chan a)
    Chan.newChan
    {-# INLINABLE newChan #-}

    -- | Generalized version of 'Chan.writeChan'.
    writeChan :: MonadBase IO m => Chan a -> a -> m ()
    writeChan :: Chan a -> a -> m ()
    writeChan chan :: Chan a
    chan = IO () -> m ()
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase (IO () -> m ()) -> (a -> IO ()) -> a -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Chan a -> a -> IO ()
    forall a. Chan a -> a -> IO ()
    Chan.writeChan Chan a
    chan
    {-# INLINABLE writeChan #-}

    -- | Generalized version of 'Chan.readChan'.
    readChan :: MonadBase IO m => Chan a -> m a
    readChan :: Chan a -> m a
    readChan = IO a -> m a
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase (IO a -> m a) -> (Chan a -> IO a) -> Chan a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Chan a -> IO a
    forall a. Chan a -> IO a
    Chan.readChan
    {-# INLINABLE readChan #-}

    -- | Generalized version of 'Chan.dupChan'.
    dupChan :: MonadBase IO m => Chan a -> m (Chan a)
    dupChan :: Chan a -> m (Chan a)
    dupChan = IO (Chan a) -> m (Chan a)
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase (IO (Chan a) -> m (Chan a))
    -> (Chan a -> IO (Chan a)) -> Chan a -> m (Chan a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Chan a -> IO (Chan a)
    forall a. Chan a -> IO (Chan a)
    Chan.dupChan
    {-# INLINABLE dupChan #-}

    -- | Generalized version of 'Chan.getChanContents'.
    getChanContents :: MonadBase IO m => Chan a -> m [a]
    getChanContents :: Chan a -> m [a]
    getChanContents = IO [a] -> m [a]
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase (IO [a] -> m [a]) -> (Chan a -> IO [a]) -> Chan a -> m [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Chan a -> IO [a]
    forall a. Chan a -> IO [a]
    Chan.getChanContents
    {-# INLINABLE getChanContents #-}

    -- | Generalized version of 'Chan.writeList2Chan'.
    writeList2Chan :: MonadBase IO m => Chan a -> [a] -> m ()
    writeList2Chan :: Chan a -> [a] -> m ()
    writeList2Chan chan :: Chan a
    chan = IO () -> m ()
    forall (b :: * -> *) (m :: * -> *) α. MonadBase b m => b α -> m α
    liftBase (IO () -> m ()) -> ([a] -> IO ()) -> [a] -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Chan a -> [a] -> IO ()
    forall a. Chan a -> [a] -> IO ()
    Chan.writeList2Chan Chan a
    chan
    {-# INLINABLE writeList2Chan #-}