    -- |
    -- Strict Deque API lifted to a Reader monad, \"mtl\"-style.
    module Deque.Strict.Reader where

    import Deque.Prelude hiding (dropWhile, head, init, last, null, reverse, tail, takeWhile)
    import qualified Deque.Prelude as Prelude
    import Deque.Strict (Deque)
    import qualified Deque.Strict as Deque

    -- |
    -- \(\mathcal{O}(n)\).
    -- Modify each element of the queue.
    map :: (MonadReader (Deque a) m) => (a -> b) -> m (Deque b)
    map :: forall a (m :: * -> *) b.
    MonadReader (Deque a) m =>
    (a -> b) -> m (Deque b)
    map a -> b
    f = (Deque a -> Deque b) -> m (Deque b)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((a -> b) -> Deque a -> Deque b
    forall a b. (a -> b) -> Deque a -> Deque b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f)

    -- |
    -- \(\mathcal{O}(n)\).
    -- Add elements to the begginning.
    prepend :: (MonadReader (Deque a) m) => Deque a -> m (Deque a)
    prepend :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    Deque a -> m (Deque a)
    prepend Deque a
    deque = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader (Deque a
    deque Deque a -> Deque a -> Deque a
    forall a. Semigroup a => a -> a -> a
    <>)

    -- |
    -- \(\mathcal{O}(n)\).
    -- Add elements to the ending.
    append :: (MonadReader (Deque a) m) => Deque a -> m (Deque a)
    append :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    Deque a -> m (Deque a)
    append Deque a
    deque = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader (Deque a -> Deque a -> Deque a
    forall a. Semigroup a => a -> a -> a
    <> Deque a
    deque)

    -- |
    -- \(\mathcal{O}(1)\).
    -- Add element in the beginning.
    cons :: (MonadReader (Deque a) m) => a -> m (Deque a)
    cons :: forall a (m :: * -> *). MonadReader (Deque a) m => a -> m (Deque a)
    cons a
    a = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader (a -> Deque a -> Deque a
    forall a. a -> Deque a -> Deque a
    Deque.cons a
    a)

    -- |
    -- \(\mathcal{O}(1)\).
    -- Add element in the ending.
    snoc :: (MonadReader (Deque a) m) => a -> m (Deque a)
    snoc :: forall a (m :: * -> *). MonadReader (Deque a) m => a -> m (Deque a)
    snoc a
    a = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader (a -> Deque a -> Deque a
    forall a. a -> Deque a -> Deque a
    Deque.snoc a
    a)

    -- |
    -- \(\mathcal{O}(1)\).
    -- Reverse the deque.
    reverse :: (MonadReader (Deque a) m) => m (Deque a)
    reverse :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Deque a)
    reverse = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Deque a
    forall a. Deque a -> Deque a
    Deque.reverse

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Move the first element to the end.
    shiftLeft :: (MonadReader (Deque a) m) => m (Deque a)
    shiftLeft :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Deque a)
    shiftLeft = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Deque a
    forall a. Deque a -> Deque a
    Deque.shiftLeft

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Move the last element to the beginning.
    shiftRight :: (MonadReader (Deque a) m) => m (Deque a)
    shiftRight :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Deque a)
    shiftRight = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Deque a
    forall a. Deque a -> Deque a
    Deque.shiftRight

    -- |
    -- \(\mathcal{O}(n)\).
    -- Leave only the elements satisfying the predicate.
    filter :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a)
    filter :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    (a -> Bool) -> m (Deque a)
    filter a -> Bool
    predicate = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((a -> Bool) -> Deque a -> Deque a
    forall a. (a -> Bool) -> Deque a -> Deque a
    Deque.filter a -> Bool
    predicate)

    -- |
    -- \(\mathcal{O}(n)\).
    -- Leave only the specified amount of first elements.
    take :: (MonadReader (Deque a) m) => Int -> m (Deque a)
    take :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    Int -> m (Deque a)
    take = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((Deque a -> Deque a) -> m (Deque a))
    -> (Int -> Deque a -> Deque a) -> Int -> m (Deque a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Int -> Deque a -> Deque a
    forall a. Int -> Deque a -> Deque a
    Deque.take

    -- |
    -- \(\mathcal{O}(n)\).
    -- Drop the specified amount of first elements.
    drop :: (MonadReader (Deque a) m) => Int -> m (Deque a)
    drop :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    Int -> m (Deque a)
    drop = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((Deque a -> Deque a) -> m (Deque a))
    -> (Int -> Deque a -> Deque a) -> Int -> m (Deque a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Int -> Deque a -> Deque a
    forall a. Int -> Deque a -> Deque a
    Deque.drop

    -- |
    -- \(\mathcal{O}(n)\).
    -- Leave only the first elements satisfying the predicate.
    takeWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a)
    takeWhile :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    (a -> Bool) -> m (Deque a)
    takeWhile a -> Bool
    predicate = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((a -> Bool) -> Deque a -> Deque a
    forall a. (a -> Bool) -> Deque a -> Deque a
    Deque.takeWhile a -> Bool
    predicate)

    -- |
    -- \(\mathcal{O}(n)\).
    -- Drop the first elements satisfying the predicate.
    dropWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a)
    dropWhile :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    (a -> Bool) -> m (Deque a)
    dropWhile a -> Bool
    predicate = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((a -> Bool) -> Deque a -> Deque a
    forall a. (a -> Bool) -> Deque a -> Deque a
    Deque.dropWhile a -> Bool
    predicate)

    -- |
    -- \(\mathcal{O}(n)\).
    -- Same as @(,) '<$>' `takeWhile` predicate '<*>' `dropWhile` predicate@.
    span :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a, Deque a)
    span :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    (a -> Bool) -> m (Deque a, Deque a)
    span a -> Bool
    predicate = (Deque a -> (Deque a, Deque a)) -> m (Deque a, Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader ((a -> Bool) -> Deque a -> (Deque a, Deque a)
    forall a. (a -> Bool) -> Deque a -> (Deque a, Deque a)
    Deque.span a -> Bool
    predicate)

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Get the first element and deque without it if it's not empty.
    uncons :: (MonadReader (Deque a) m) => m (Maybe a, Deque a)
    uncons :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    m (Maybe a, Deque a)
    uncons =
      (Deque a -> (Maybe a, Deque a)) -> m (Maybe a, Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader
        ( \Deque a
    deque -> case Deque a -> Maybe (a, Deque a)
    forall a. Deque a -> Maybe (a, Deque a)
    Deque.uncons Deque a
    deque of
            Maybe (a, Deque a)
    Nothing -> (Maybe a
    forall a. Maybe a
    Nothing, Deque a
    deque)
            Just (a
    a, Deque a
    newDeque) -> (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a, Deque a
    newDeque)
        )

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Get the last element and deque without it if it's not empty.
    unsnoc :: (MonadReader (Deque a) m) => m (Maybe a, Deque a)
    unsnoc :: forall a (m :: * -> *).
    MonadReader (Deque a) m =>
    m (Maybe a, Deque a)
    unsnoc =
      (Deque a -> (Maybe a, Deque a)) -> m (Maybe a, Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader
        ( \Deque a
    deque -> case Deque a -> Maybe (a, Deque a)
    forall a. Deque a -> Maybe (a, Deque a)
    Deque.unsnoc Deque a
    deque of
            Maybe (a, Deque a)
    Nothing -> (Maybe a
    forall a. Maybe a
    Nothing, Deque a
    deque)
            Just (a
    a, Deque a
    newDeque) -> (a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a, Deque a
    newDeque)
        )

    -- |
    -- \(\mathcal{O}(1)\).
    -- Check whether deque is empty.
    null :: (MonadReader (Deque a) m) => m Bool
    null :: forall a (m :: * -> *). MonadReader (Deque a) m => m Bool
    null = (Deque a -> Bool) -> m Bool
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Bool
    forall a. Deque a -> Bool
    Deque.null

    -- |
    -- \(\mathcal{O}(1)\).
    -- Check whether deque is empty.
    length :: (MonadReader (Deque a) m) => m Int
    length :: forall a (m :: * -> *). MonadReader (Deque a) m => m Int
    length = (Deque a -> Int) -> m Int
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Int
    forall a. Deque a -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    Prelude.length

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Get the first element if deque is not empty.
    head :: (MonadReader (Deque a) m) => m (Maybe a)
    head :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Maybe a)
    head = (Deque a -> Maybe a) -> m (Maybe a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Maybe a
    forall a. Deque a -> Maybe a
    Deque.head

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Get the last element if deque is not empty.
    last :: (MonadReader (Deque a) m) => m (Maybe a)
    last :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Maybe a)
    last = (Deque a -> Maybe a) -> m (Maybe a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Maybe a
    forall a. Deque a -> Maybe a
    Deque.last

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Keep all elements but the first one.
    tail :: (MonadReader (Deque a) m) => m (Deque a)
    tail :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Deque a)
    tail = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Deque a
    forall a. Deque a -> Deque a
    Deque.tail

    -- |
    -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\).
    -- Keep all elements but the last one.
    init :: (MonadReader (Deque a) m) => m (Deque a)
    init :: forall a (m :: * -> *). MonadReader (Deque a) m => m (Deque a)
    init = (Deque a -> Deque a) -> m (Deque a)
    forall a. (Deque a -> a) -> m a
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    reader Deque a -> Deque a
    forall a. Deque a -> Deque a
    Deque.init