    {-# LANGUAGE
            CPP,
            MultiParamTypeClasses,
            FlexibleInstances
      #-}

    -- |This module exports no new symbols of its own.  It defines
    --  basic class instances for creating, reading, and writing 'MVar's, and
    --  re-exports 'MVar'.
    module Data.MRef.Instances
        ( MVar
        , MonadIO(..)

    #ifdef useSTM
        , module Data.MRef.Instances.STM
    #endif
        ) where

    #ifdef useSTM
    import Data.MRef.Instances.STM
    #endif

    import Data.MRef.Types

    import Control.Concurrent.MVar
    import Control.Monad.Trans

    -- preferred instances
    -- MVar in IO monad
    instance HasMRef IO where
        newMRef :: forall a. a -> IO (MRef IO a)
    newMRef a
    x    = (MVar a -> MRef IO a) -> IO (MVar a) -> IO (MRef IO a)
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MVar a -> MRef IO a
    forall sr (m :: * -> *) a.
    (TakeMRef sr m a, PutMRef sr m a) =>
    sr -> MRef m a
    MRef (a -> IO (MVar a)
    forall a. a -> IO (MVar a)
    newMVar a
    x)
        newEmptyMRef :: forall a. IO (MRef IO a)
    newEmptyMRef = (MVar a -> MRef IO a) -> IO (MVar a) -> IO (MRef IO a)
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap MVar a -> MRef IO a
    forall sr (m :: * -> *) a.
    (TakeMRef sr m a, PutMRef sr m a) =>
    sr -> MRef m a
    MRef IO (MVar a)
    forall a. IO (MVar a)
    newEmptyMVar
    instance MonadIO m => NewMRef (MVar a) m a where
        newMReference :: a -> m (MVar a)
    newMReference = IO (MVar a) -> m (MVar a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (MVar a) -> m (MVar a))
    -> (a -> IO (MVar a)) -> a -> m (MVar a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> IO (MVar a)
    forall a. a -> IO (MVar a)
    newMVar
        newEmptyMReference :: m (MVar a)
    newEmptyMReference = IO (MVar a) -> m (MVar a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO (MVar a)
    forall a. IO (MVar a)
    newEmptyMVar
    instance MonadIO m => TakeMRef (MVar a) m a where
        takeMReference :: MVar a -> m a
    takeMReference = IO a -> m a
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO a -> m a) -> (MVar a -> IO a) -> MVar a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MVar a -> IO a
    forall a. MVar a -> IO a
    takeMVar
    instance MonadIO m => PutMRef (MVar a) m a where
        putMReference :: MVar a -> a -> m ()
    putMReference MVar a
    r = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> (a -> IO ()) -> a -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MVar a -> a -> IO ()
    forall a. MVar a -> a -> IO ()
    putMVar MVar a
    r