    {-# LANGUAGE ConstraintKinds   #-}
    {-# LANGUAGE FlexibleContexts  #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE TypeFamilies      #-}
    -- | Various typeclasses for mutable containers.
    module Data.Mutable.Class
        ( PrimMonad
        , PrimState
        , RealWorld
        , MutableQueue
        , MutableStack
        , MutableDeque
        , IORef
        , asIORef
        , STRef
        , asSTRef
        , MutVar
        , asMutVar
        , MutableContainer (..)
        , MutableRef (..)
        , MutableAtomicRef (..)
        , MutableCollection (..)
        , MutablePushFront (..)
        , MutablePushBack (..)
        , MutablePopFront (..)
        , MutablePopBack (..)
        , pushFrontRef
        , pushBackRef
        , popFrontRef
        , popBackRef
        ) where

    import           Control.Monad.Primitive
    import           Data.IORef
    import           Data.Monoid
    import           Data.MonoTraversable    (Element)
    import           Data.Primitive.MutVar
    import qualified Data.Sequences          as Seqs
    import           Data.STRef

    -- | The parent typeclass for all mutable containers.
    --
    -- Since 0.2.0
    class MutableContainer c where
        -- | Associated type giving the primitive state token for the given
        -- container, much like 'PrimState' from primitive.
        --
        -- Since 0.2.0
        type MCState c

    instance MutableContainer (IORef a) where
        type MCState (IORef a) = PrimState IO
    instance MutableContainer (STRef s a) where
        type MCState (STRef s a) = s
    instance MutableContainer (MutVar s a) where
        type MCState (MutVar s a) = s

    -- | Typeclass for single-cell mutable references.
    --
    -- Since 0.2.0
    class MutableContainer c => MutableRef c where
        -- | Associated type giving the type of the value inside the mutable
        -- reference.
        --
        -- Since 0.2.0
        type RefElement c

        -- | Create a new mutable reference with the given value.
        --
        -- Since 0.2.0
        newRef :: (PrimMonad m, PrimState m ~ MCState c)
               => RefElement c
               -> m c

        -- | Read the current value in the mutable reference.
        --
        -- Since 0.2.0
        readRef :: (PrimMonad m, PrimState m ~ MCState c)
                => c
                -> m (RefElement c)

        -- | Write a new value to the mutable reference.
        --
        -- Since 0.2.0
        writeRef :: (PrimMonad m, PrimState m ~ MCState c)
                 => c
                 -> RefElement c
                 -> m ()

        -- | Modify the value in the mutable reference, without necessarily forcing the result.
        --
        -- Note: some implementations /will/ force the result, in particular
        -- @PRef@, @SRef@, and @URef@.
        --
        -- Since 0.2.0
        modifyRef :: (PrimMonad m, PrimState m ~ MCState c)
                  => c
                  -> (RefElement c -> RefElement c)
                  -> m ()

        -- | Modify the value in the mutable reference, forcing the result.
        --
        -- Since 0.2.0
        modifyRef' :: (PrimMonad m, PrimState m ~ MCState c)
                   => c
                   -> (RefElement c -> RefElement c)
                   -> m ()

    instance MutableRef (IORef a) where
        type RefElement (IORef a) = a
        newRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    RefElement (IORef a) -> m (IORef a)
    newRef = IO (IORef a) -> m (IORef a)
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO (IORef a) -> m (IORef a))
    -> (a -> IO (IORef a)) -> a -> m (IORef a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> IO (IORef a)
    forall a. a -> IO (IORef a)
    newIORef
        {-# INLINE newRef #-}
        readRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> m (RefElement (IORef a))
    readRef = IO a -> m a
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO a -> m a) -> (IORef a -> IO a) -> IORef a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> IO a
    forall a. IORef a -> IO a
    readIORef
        {-# INLINE readRef #-}
        writeRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> RefElement (IORef a) -> m ()
    writeRef IORef a
    c = IO () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO () -> m ()) -> (a -> IO ()) -> a -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> a -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef IORef a
    c
        {-# INLINE writeRef #-}
        modifyRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> (RefElement (IORef a) -> RefElement (IORef a)) -> m ()
    modifyRef IORef a
    c = IO () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO () -> m ()) -> ((a -> a) -> IO ()) -> (a -> a) -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> (a -> a) -> IO ()
    forall a. IORef a -> (a -> a) -> IO ()
    modifyIORef IORef a
    c
        {-# INLINE modifyRef #-}
        modifyRef' :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> (RefElement (IORef a) -> RefElement (IORef a)) -> m ()
    modifyRef' IORef a
    c = IO () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO () -> m ()) -> ((a -> a) -> IO ()) -> (a -> a) -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> (a -> a) -> IO ()
    forall a. IORef a -> (a -> a) -> IO ()
    modifyIORef' IORef a
    c
        {-# INLINE modifyRef' #-}
    instance MutableRef (STRef s a) where
        type RefElement (STRef s a) = a
        newRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    RefElement (STRef s a) -> m (STRef s a)
    newRef = ST s (STRef s a) -> m (STRef s a)
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (ST s (STRef s a) -> m (STRef s a))
    -> (a -> ST s (STRef s a)) -> a -> m (STRef s a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ST s (STRef s a)
    forall a s. a -> ST s (STRef s a)
    newSTRef
        {-# INLINE newRef #-}
        readRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> m (RefElement (STRef s a))
    readRef = ST s a -> m a
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (ST s a -> m a) -> (STRef s a -> ST s a) -> STRef s a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STRef s a -> ST s a
    forall s a. STRef s a -> ST s a
    readSTRef
        {-# INLINE readRef #-}
        writeRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> RefElement (STRef s a) -> m ()
    writeRef STRef s a
    c = ST s () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (ST s () -> m ()) -> (a -> ST s ()) -> a -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STRef s a -> a -> ST s ()
    forall s a. STRef s a -> a -> ST s ()
    writeSTRef STRef s a
    c
        {-# INLINE writeRef #-}
        modifyRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a
    -> (RefElement (STRef s a) -> RefElement (STRef s a)) -> m ()
    modifyRef STRef s a
    c = ST s () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (ST s () -> m ()) -> ((a -> a) -> ST s ()) -> (a -> a) -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STRef s a -> (a -> a) -> ST s ()
    forall s a. STRef s a -> (a -> a) -> ST s ()
    modifySTRef STRef s a
    c
        {-# INLINE modifyRef #-}
        modifyRef' :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a
    -> (RefElement (STRef s a) -> RefElement (STRef s a)) -> m ()
    modifyRef' STRef s a
    c = ST s () -> m ()
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (ST s () -> m ()) -> ((a -> a) -> ST s ()) -> (a -> a) -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STRef s a -> (a -> a) -> ST s ()
    forall s a. STRef s a -> (a -> a) -> ST s ()
    modifySTRef' STRef s a
    c
        {-# INLINE modifyRef' #-}
    instance MutableRef (MutVar s a) where
        type RefElement (MutVar s a) = a
        newRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    RefElement (MutVar s a) -> m (MutVar s a)
    newRef = a -> m (MutVar (PrimState m) a)
    RefElement (MutVar s a) -> m (MutVar s a)
    forall (m :: * -> *) a.
    PrimMonad m =>
    a -> m (MutVar (PrimState m) a)
    newMutVar
        {-# INLINE newRef #-}
        readRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> m (RefElement (MutVar s a))
    readRef = MutVar s a -> m (RefElement (MutVar s a))
    MutVar (PrimState m) a -> m a
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutVar (PrimState m) a -> m a
    readMutVar
        {-# INLINE readRef #-}
        writeRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> RefElement (MutVar s a) -> m ()
    writeRef = MutVar s a -> RefElement (MutVar s a) -> m ()
    MutVar (PrimState m) a -> a -> m ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutVar (PrimState m) a -> a -> m ()
    writeMutVar
        {-# INLINE writeRef #-}
        modifyRef :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a
    -> (RefElement (MutVar s a) -> RefElement (MutVar s a)) -> m ()
    modifyRef = MutVar s a
    -> (RefElement (MutVar s a) -> RefElement (MutVar s a)) -> m ()
    MutVar (PrimState m) a -> (a -> a) -> m ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutVar (PrimState m) a -> (a -> a) -> m ()
    modifyMutVar
        {-# INLINE modifyRef #-}
        modifyRef' :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a
    -> (RefElement (MutVar s a) -> RefElement (MutVar s a)) -> m ()
    modifyRef' = MutVar s a
    -> (RefElement (MutVar s a) -> RefElement (MutVar s a)) -> m ()
    MutVar (PrimState m) a -> (a -> a) -> m ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MutVar (PrimState m) a -> (a -> a) -> m ()
    modifyMutVar'
        {-# INLINE modifyRef' #-}

    -- | @MutableRef@s that provide for atomic modifications of their contents.
    --
    -- Since 0.2.0
    class MutableRef c => MutableAtomicRef c where
        -- | Modify the value without necessarily forcing the result.
        --
        -- Since 0.2.0
        atomicModifyRef
            :: (PrimMonad m, PrimState m ~ MCState c)
            => c
            -> (RefElement c -> (RefElement c, a))
            -> m a

        -- | Modify the value, forcing the result.
        --
        -- Since 0.2.0
        atomicModifyRef'
            :: (PrimMonad m, PrimState m ~ MCState c)
            => c
            -> (RefElement c -> (RefElement c, a))
            -> m a
    instance MutableAtomicRef (IORef a) where
        atomicModifyRef :: forall (m :: * -> *) a.
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a
    -> (RefElement (IORef a) -> (RefElement (IORef a), a)) -> m a
    atomicModifyRef IORef a
    c = IO a -> m a
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO a -> m a) -> ((a -> (a, a)) -> IO a) -> (a -> (a, a)) -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> (a -> (a, a)) -> IO a
    forall a b. IORef a -> (a -> (a, b)) -> IO b
    atomicModifyIORef IORef a
    c
        {-# INLINE atomicModifyRef #-}
        atomicModifyRef' :: forall (m :: * -> *) a.
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a
    -> (RefElement (IORef a) -> (RefElement (IORef a), a)) -> m a
    atomicModifyRef' IORef a
    c = IO a -> m a
    forall (m1 :: * -> *) (m2 :: * -> *) a.
    (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2) =>
    m1 a -> m2 a
    primToPrim (IO a -> m a) -> ((a -> (a, a)) -> IO a) -> (a -> (a, a)) -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IORef a -> (a -> (a, a)) -> IO a
    forall a b. IORef a -> (a -> (a, b)) -> IO b
    atomicModifyIORef' IORef a
    c
        {-# INLINE atomicModifyRef' #-}
    instance MutableAtomicRef (MutVar s a) where
        atomicModifyRef :: forall (m :: * -> *) a.
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a
    -> (RefElement (MutVar s a) -> (RefElement (MutVar s a), a)) -> m a
    atomicModifyRef = MutVar s a
    -> (RefElement (MutVar s a) -> (RefElement (MutVar s a), a)) -> m a
    MutVar (PrimState m) a -> (a -> (a, a)) -> m a
    forall (m :: * -> *) a b.
    PrimMonad m =>
    MutVar (PrimState m) a -> (a -> (a, b)) -> m b
    atomicModifyMutVar
        {-# INLINE atomicModifyRef #-}
        atomicModifyRef' :: forall (m :: * -> *) a.
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a
    -> (RefElement (MutVar s a) -> (RefElement (MutVar s a), a)) -> m a
    atomicModifyRef' = MutVar s a
    -> (RefElement (MutVar s a) -> (RefElement (MutVar s a), a)) -> m a
    MutVar (PrimState m) a -> (a -> (a, a)) -> m a
    forall (m :: * -> *) a b.
    PrimMonad m =>
    MutVar (PrimState m) a -> (a -> (a, b)) -> m b
    atomicModifyMutVar'
        {-# INLINE atomicModifyRef' #-}

    -- | Containers which contain 0 or more values.
    --
    -- Since 0.2.0
    class MutableContainer c => MutableCollection c where
        -- | The type of each value in the collection.
        --
        -- Since 0.2.0
        type CollElement c

        -- | Create a new, empty collection.
        --
        -- Since 0.2.0
        newColl :: (PrimMonad m, PrimState m ~ MCState c)
                => m c
    instance Data.Monoid.Monoid w => MutableCollection (IORef w) where
        type CollElement (IORef w) = Element w
        newColl :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef w)) =>
    m (IORef w)
    newColl = RefElement (IORef w) -> m (IORef w)
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    RefElement c -> m c
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef w)) =>
    RefElement (IORef w) -> m (IORef w)
    newRef w
    RefElement (IORef w)
    forall a. Monoid a => a
    mempty
        {-# INLINE newColl #-}
    instance Monoid w => MutableCollection (STRef s w) where
        type CollElement (STRef s w) = Element w
        newColl :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s w)) =>
    m (STRef s w)
    newColl = RefElement (STRef s w) -> m (STRef s w)
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    RefElement c -> m c
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s w)) =>
    RefElement (STRef s w) -> m (STRef s w)
    newRef w
    RefElement (STRef s w)
    forall a. Monoid a => a
    mempty
        {-# INLINE newColl #-}
    instance Monoid w => MutableCollection (MutVar s w) where
        type CollElement (MutVar s w) = Element w
        newColl :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s w)) =>
    m (MutVar s w)
    newColl = RefElement (MutVar s w) -> m (MutVar s w)
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    RefElement c -> m c
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s w)) =>
    RefElement (MutVar s w) -> m (MutVar s w)
    newRef w
    RefElement (MutVar s w)
    forall a. Monoid a => a
    mempty
        {-# INLINE newColl #-}

    -- | Take a value from the front of the collection, if available.
    --
    -- Since 0.2.0
    class MutableCollection c => MutablePopFront c where
        -- | Take a value from the front of the collection, if available.
        --
        -- Since 0.2.0
        popFront :: (PrimMonad m, PrimState m ~ MCState c)
                 => c
                 -> m (Maybe (CollElement c))
    popFrontRef
        :: ( PrimMonad m
           , PrimState m ~ MCState c
           , MutableRef c
           , CollElement c ~ Element (RefElement c)
           , Seqs.IsSequence (RefElement c)
           )
        => c
        -> m (Maybe (CollElement c))
    popFrontRef :: forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popFrontRef c
    c = do
        l <- c -> m (RefElement c)
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> m (RefElement c)
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> m (RefElement c)
    readRef c
    c
        case Seqs.uncons l of
            Maybe (Element (RefElement c), RefElement c)
    Nothing -> Maybe (CollElement c) -> m (Maybe (CollElement c))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (CollElement c)
    forall a. Maybe a
    Nothing
            Just (Element (RefElement c)
    x, RefElement c
    xs) -> do
                c -> RefElement c -> m ()
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> RefElement c -> m ()
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> RefElement c -> m ()
    writeRef c
    c RefElement c
    xs
                Maybe (CollElement c) -> m (Maybe (CollElement c))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CollElement c -> Maybe (CollElement c)
    forall a. a -> Maybe a
    Just Element (RefElement c)
    CollElement c
    x)
    {-# INLINE popFrontRef #-}
    instance Seqs.IsSequence a => MutablePopFront (IORef a) where
        popFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> m (Maybe (CollElement (IORef a)))
    popFront = IORef a -> m (Maybe (CollElement (IORef a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popFrontRef
        {-# INLINE popFront #-}
    instance Seqs.IsSequence a => MutablePopFront (STRef s a) where
        popFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> m (Maybe (CollElement (STRef s a)))
    popFront = STRef s a -> m (Maybe (CollElement (STRef s a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popFrontRef
        {-# INLINE popFront #-}
    instance Seqs.IsSequence a => MutablePopFront (MutVar s a) where
        popFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> m (Maybe (CollElement (MutVar s a)))
    popFront = MutVar s a -> m (Maybe (CollElement (MutVar s a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popFrontRef
        {-# INLINE popFront #-}

    -- | Place a value at the front of the collection.
    --
    -- Since 0.2.0
    class MutableCollection c => MutablePushFront c where
        -- | Place a value at the front of the collection.
        --
        -- Since 0.2.0
        pushFront :: (PrimMonad m, PrimState m ~ MCState c)
                  => c
                  -> CollElement c
                  -> m ()
    pushFrontRef
        :: ( PrimMonad m
           , PrimState m ~ MCState c
           , MutableRef c
           , CollElement c ~ Element (RefElement c)
           , Seqs.IsSequence (RefElement c)
           )
        => c
        -> CollElement c
        -> m ()
    pushFrontRef :: forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushFrontRef c
    c CollElement c
    e = c -> (RefElement c -> RefElement c) -> m ()
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> (RefElement c -> RefElement c) -> m ()
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> (RefElement c -> RefElement c) -> m ()
    modifyRef' c
    c (Element (RefElement c) -> RefElement c -> RefElement c
    forall seq. SemiSequence seq => Element seq -> seq -> seq
    Seqs.cons Element (RefElement c)
    CollElement c
    e)
    {-# INLINE pushFrontRef #-}
    instance Seqs.IsSequence a => MutablePushFront (IORef a) where
        pushFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> CollElement (IORef a) -> m ()
    pushFront = IORef a -> CollElement (IORef a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushFrontRef
        {-# INLINE pushFront #-}
    instance Seqs.IsSequence a => MutablePushFront (STRef s a) where
        pushFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> CollElement (STRef s a) -> m ()
    pushFront = STRef s a -> CollElement (STRef s a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushFrontRef
        {-# INLINE pushFront #-}
    instance Seqs.IsSequence a => MutablePushFront (MutVar s a) where
        pushFront :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> CollElement (MutVar s a) -> m ()
    pushFront = MutVar s a -> CollElement (MutVar s a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushFrontRef
        {-# INLINE pushFront #-}

    -- | Take a value from the back of the collection, if available.
    --
    -- Since 0.2.0
    class MutableCollection c => MutablePopBack c where
        -- | Take a value from the back of the collection, if available.
        --
        -- Since 0.2.0
        popBack :: (PrimMonad m, PrimState m ~ MCState c)
                => c
                -> m (Maybe (CollElement c))
    popBackRef
        :: ( PrimMonad m
           , PrimState m ~ MCState c
           , MutableRef c
           , CollElement c ~ Element (RefElement c)
           , Seqs.IsSequence (RefElement c)
           )
        => c
        -> m (Maybe (CollElement c))
    popBackRef :: forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popBackRef c
    c = do
        l <- c -> m (RefElement c)
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> m (RefElement c)
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> m (RefElement c)
    readRef c
    c
        case Seqs.unsnoc l of
            Maybe (RefElement c, Element (RefElement c))
    Nothing -> Maybe (CollElement c) -> m (Maybe (CollElement c))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (CollElement c)
    forall a. Maybe a
    Nothing
            Just (RefElement c
    xs, Element (RefElement c)
    x) -> do
                c -> RefElement c -> m ()
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> RefElement c -> m ()
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> RefElement c -> m ()
    writeRef c
    c RefElement c
    xs
                Maybe (CollElement c) -> m (Maybe (CollElement c))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CollElement c -> Maybe (CollElement c)
    forall a. a -> Maybe a
    Just Element (RefElement c)
    CollElement c
    x)
    {-# INLINE popBackRef #-}
    instance Seqs.IsSequence a => MutablePopBack (IORef a) where
        popBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> m (Maybe (CollElement (IORef a)))
    popBack = IORef a -> m (Maybe (CollElement (IORef a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popBackRef
        {-# INLINE popBack #-}
    instance Seqs.IsSequence a => MutablePopBack (STRef s a) where
        popBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> m (Maybe (CollElement (STRef s a)))
    popBack = STRef s a -> m (Maybe (CollElement (STRef s a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popBackRef
        {-# INLINE popBack #-}
    instance Seqs.IsSequence a => MutablePopBack (MutVar s a) where
        popBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> m (Maybe (CollElement (MutVar s a)))
    popBack = MutVar s a -> m (Maybe (CollElement (MutVar s a)))
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> m (Maybe (CollElement c))
    popBackRef
        {-# INLINE popBack #-}

    -- | Place a value at the back of the collection.
    --
    -- Since 0.2.0
    class MutableCollection c => MutablePushBack c where
        -- | Place a value at the back of the collection.
        --
        -- Since 0.2.0
        pushBack :: (PrimMonad m, PrimState m ~ MCState c)
                 => c
                 -> CollElement c
                 -> m ()
    pushBackRef
        :: ( PrimMonad m
           , PrimState m ~ MCState c
           , MutableRef c
           , CollElement c ~ Element (RefElement c)
           , Seqs.IsSequence (RefElement c)
           )
        => c
        -> CollElement c
        -> m ()
    pushBackRef :: forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushBackRef c
    c CollElement c
    e = c -> (RefElement c -> RefElement c) -> m ()
    forall c (m :: * -> *).
    (MutableRef c, PrimMonad m, PrimState m ~ MCState c) =>
    c -> (RefElement c -> RefElement c) -> m ()
    forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState c) =>
    c -> (RefElement c -> RefElement c) -> m ()
    modifyRef' c
    c (RefElement c -> Element (RefElement c) -> RefElement c
    forall seq. SemiSequence seq => seq -> Element seq -> seq
    `Seqs.snoc` Element (RefElement c)
    CollElement c
    e)
    {-# INLINE pushBackRef #-}
    instance Seqs.IsSequence a => MutablePushBack (IORef a) where
        pushBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (IORef a)) =>
    IORef a -> CollElement (IORef a) -> m ()
    pushBack = IORef a -> CollElement (IORef a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushBackRef
        {-# INLINE pushBack #-}
    instance Seqs.IsSequence a => MutablePushBack (STRef s a) where
        pushBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (STRef s a)) =>
    STRef s a -> CollElement (STRef s a) -> m ()
    pushBack = STRef s a -> CollElement (STRef s a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushBackRef
        {-# INLINE pushBack #-}
    instance Seqs.IsSequence a => MutablePushBack (MutVar s a) where
        pushBack :: forall (m :: * -> *).
    (PrimMonad m, PrimState m ~ MCState (MutVar s a)) =>
    MutVar s a -> CollElement (MutVar s a) -> m ()
    pushBack = MutVar s a -> CollElement (MutVar s a) -> m ()
    forall (m :: * -> *) c.
    (PrimMonad m, PrimState m ~ MCState c, MutableRef c,
     CollElement c ~ Element (RefElement c),
     IsSequence (RefElement c)) =>
    c -> CollElement c -> m ()
    pushBackRef
        {-# INLINE pushBack #-}

    -- | Collections which allow pushing and popping at the front (aka FIFOs).
    --
    -- Since 0.2.0
    type MutableQueue c = (MutablePopFront c, MutablePushBack c)

    -- | Collections which allow pushing at the back and popping at the front (aka FILOs).
    --
    -- Since 0.2.0
    type MutableStack c = (MutablePopFront c, MutablePushFront c)

    -- | Collections which allow pushing and popping at the front and back.
    --
    -- Since 0.2.0
    type MutableDeque c = (MutableQueue c, MutablePushFront c, MutablePopBack c)

    -- |
    -- Since 0.2.0
    asIORef :: IORef a -> IORef a
    asIORef :: forall a. IORef a -> IORef a
    asIORef = IORef a -> IORef a
    forall a. a -> a
    id

    -- |
    -- Since 0.2.0
    asSTRef :: STRef s a -> STRef s a
    asSTRef :: forall s a. STRef s a -> STRef s a
    asSTRef = STRef s a -> STRef s a
    forall a. a -> a
    id

    -- |
    -- Since 0.2.0
    asMutVar :: MutVar s a -> MutVar s a
    asMutVar :: forall s a. MutVar s a -> MutVar s a
    asMutVar = MutVar s a -> MutVar s a
    forall a. a -> a
    id