io-sim-1.10.1.0: src/Data/Deque/Strict.hs
{-# LANGUAGE CPP #-}
-- | A minimal implementation of a strict deque.
--
module Data.Deque.Strict where
#if __GLASGOW_HASKELL__ >= 910
import Data.Foldable (foldr')
#else
import Data.Foldable (foldl', foldr')
#endif
import Data.List qualified as List
import Prelude hiding (head, init, tail)
data Deque a = Deque ![a] ![a]
instance Semigroup (Deque a) where
Deque as bs <> Deque as' bs' =
Deque as (bs' ++ reverse as' ++ bs)
instance Monoid (Deque a) where
mempty = Deque [] []
instance Foldable Deque where
foldr step init (Deque head tail) =
foldr step (foldl' (flip step) init tail) head
foldl' step init (Deque head tail) =
foldr' (flip step) (foldl' step init head) tail
fromList :: [a] -> Deque a
fromList as = Deque as []
snoc :: a -> Deque a -> Deque a
snoc a (Deque as bs) = Deque as (a : bs)
uncons :: Deque a -> Maybe (a, Deque a)
uncons = \case
Deque (a : head') tail -> Just (a, Deque head' tail)
Deque [] tail ->
case reverse tail of
(a : head') -> Just (a, Deque head' [])
[] -> Nothing
filter :: (a -> Bool) -> Deque a -> Deque a
filter f (Deque head tail) = Deque (List.filter f head) (List.filter f tail)