packages feed

deque 0.3.1.1 → 0.4

raw patch · 11 files changed

+985/−462 lines, 11 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Deque.Lazy: instance Control.Monad.Fail.MonadFail Deque.Lazy.Deque
- Deque.Lazy: instance Data.Foldable.Foldable Deque.Lazy.Deque
- Deque.Lazy: instance Data.Traversable.Traversable Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.Alternative Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.Applicative Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.Functor Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.Monad Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.MonadPlus Deque.Lazy.Deque
- Deque.Lazy: instance GHC.Base.Monoid (Deque.Lazy.Deque a)
- Deque.Lazy: instance GHC.Base.Semigroup (Deque.Lazy.Deque a)
- Deque.Lazy: instance GHC.Classes.Eq a => GHC.Classes.Eq (Deque.Lazy.Deque a)
- Deque.Lazy: instance GHC.Exts.IsList (Deque.Lazy.Deque a)
- Deque.Lazy: instance GHC.Show.Show a => GHC.Show.Show (Deque.Lazy.Deque a)
- Deque.Strict: instance Control.Monad.Fail.MonadFail Deque.Strict.Deque
- Deque.Strict: instance Data.Foldable.Foldable Deque.Strict.Deque
- Deque.Strict: instance Data.Traversable.Traversable Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.Alternative Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.Applicative Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.Functor Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.Monad Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.MonadPlus Deque.Strict.Deque
- Deque.Strict: instance GHC.Base.Monoid (Deque.Strict.Deque a)
- Deque.Strict: instance GHC.Base.Semigroup (Deque.Strict.Deque a)
- Deque.Strict: instance GHC.Classes.Eq a => GHC.Classes.Eq (Deque.Strict.Deque a)
- Deque.Strict: instance GHC.Exts.IsList (Deque.Strict.Deque a)
- Deque.Strict: instance GHC.Show.Show a => GHC.Show.Show (Deque.Strict.Deque a)
+ Deque.Lazy: drop :: Int -> Deque a -> Deque a
+ Deque.Lazy: fromStrict :: Deque a -> Deque a
+ Deque.Lazy: take :: Int -> Deque a -> Deque a
+ Deque.Lazy: toStrict :: Deque a -> Deque a
+ Deque.Lazy.Reader: append :: MonadReader (Deque a) m => Deque a -> m (Deque a)
+ Deque.Lazy.Reader: cons :: MonadReader (Deque a) m => a -> m (Deque a)
+ Deque.Lazy.Reader: drop :: MonadReader (Deque a) m => Int -> m (Deque a)
+ Deque.Lazy.Reader: dropWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Lazy.Reader: filter :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Lazy.Reader: head :: MonadReader (Deque a) m => m (Maybe a)
+ Deque.Lazy.Reader: init :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Lazy.Reader: last :: MonadReader (Deque a) m => m (Maybe a)
+ Deque.Lazy.Reader: length :: MonadReader (Deque a) m => m Int
+ Deque.Lazy.Reader: map :: MonadReader (Deque a) m => (a -> b) -> m (Deque b)
+ Deque.Lazy.Reader: null :: MonadReader (Deque a) m => m Bool
+ Deque.Lazy.Reader: prepend :: MonadReader (Deque a) m => Deque a -> m (Deque a)
+ Deque.Lazy.Reader: reverse :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Lazy.Reader: shiftLeft :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Lazy.Reader: shiftRight :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Lazy.Reader: snoc :: MonadReader (Deque a) m => a -> m (Deque a)
+ Deque.Lazy.Reader: tail :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Lazy.Reader: take :: MonadReader (Deque a) m => Int -> m (Deque a)
+ Deque.Lazy.Reader: takeWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Lazy.Reader: uncons :: MonadReader (Deque a) m => m (Maybe a, Deque a)
+ Deque.Lazy.Reader: unsnoc :: MonadReader (Deque a) m => m (Maybe a, Deque a)
+ Deque.Lazy.State: drop :: MonadState (Deque a) m => Int -> m ()
+ Deque.Lazy.State: take :: MonadState (Deque a) m => Int -> m ()
+ Deque.Strict: drop :: Int -> Deque a -> Deque a
+ Deque.Strict: fromLazy :: Deque a -> Deque a
+ Deque.Strict: take :: Int -> Deque a -> Deque a
+ Deque.Strict: toLazy :: Deque a -> Deque a
+ Deque.Strict.Reader: append :: MonadReader (Deque a) m => Deque a -> m (Deque a)
+ Deque.Strict.Reader: cons :: MonadReader (Deque a) m => a -> m (Deque a)
+ Deque.Strict.Reader: drop :: MonadReader (Deque a) m => Int -> m (Deque a)
+ Deque.Strict.Reader: dropWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Strict.Reader: filter :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Strict.Reader: head :: MonadReader (Deque a) m => m (Maybe a)
+ Deque.Strict.Reader: init :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Strict.Reader: last :: MonadReader (Deque a) m => m (Maybe a)
+ Deque.Strict.Reader: length :: MonadReader (Deque a) m => m Int
+ Deque.Strict.Reader: map :: MonadReader (Deque a) m => (a -> b) -> m (Deque b)
+ Deque.Strict.Reader: null :: MonadReader (Deque a) m => m Bool
+ Deque.Strict.Reader: prepend :: MonadReader (Deque a) m => Deque a -> m (Deque a)
+ Deque.Strict.Reader: reverse :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Strict.Reader: shiftLeft :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Strict.Reader: shiftRight :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Strict.Reader: snoc :: MonadReader (Deque a) m => a -> m (Deque a)
+ Deque.Strict.Reader: tail :: MonadReader (Deque a) m => m (Deque a)
+ Deque.Strict.Reader: take :: MonadReader (Deque a) m => Int -> m (Deque a)
+ Deque.Strict.Reader: takeWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)
+ Deque.Strict.Reader: uncons :: MonadReader (Deque a) m => m (Maybe a, Deque a)
+ Deque.Strict.Reader: unsnoc :: MonadReader (Deque a) m => m (Maybe a, Deque a)
+ Deque.Strict.State: drop :: MonadState (Deque a) m => Int -> m ()
+ Deque.Strict.State: take :: MonadState (Deque a) m => Int -> m ()
- Deque.Lazy.State: init :: MonadState (Deque a) m => m (Deque a)
+ Deque.Lazy.State: init :: MonadState (Deque a) m => m ()
- Deque.Lazy.State: tail :: MonadState (Deque a) m => m (Deque a)
+ Deque.Lazy.State: tail :: MonadState (Deque a) m => m ()
- Deque.Strict.State: init :: MonadState (Deque a) m => m (Deque a)
+ Deque.Strict.State: init :: MonadState (Deque a) m => m ()
- Deque.Strict.State: tail :: MonadState (Deque a) m => m (Deque a)
+ Deque.Strict.State: tail :: MonadState (Deque a) m => m ()

Files

deque.cabal view
@@ -1,5 +1,5 @@ name: deque-version: 0.3.1.1+version: 0.4 synopsis: Double-ended queues description:   Strict and lazy implementations of Double-Ended Queue (aka Dequeue or Deque)@@ -21,13 +21,18 @@ library   hs-source-dirs: library   default-extensions: BangPatterns, DeriveDataTypeable, DeriveGeneric, DeriveFunctor, DeriveTraversable, FlexibleContexts, FlexibleInstances, LambdaCase, NoImplicitPrelude, RankNTypes, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeFamilies+  ghc-options: -funbox-strict-fields   default-language: Haskell2010   exposed-modules:     Deque.Lazy+    Deque.Lazy.Reader     Deque.Lazy.State     Deque.Strict+    Deque.Strict.Reader     Deque.Strict.State   other-modules:+    Deque.Lazy.Defs+    Deque.Strict.Defs     Deque.Prelude   build-depends:     base >=4.9 && <5,
library/Deque/Lazy.hs view
@@ -6,221 +6,38 @@ -} module Deque.Lazy (-  Deque,-  fromConsAndSnocLists,-  cons,-  snoc,-  reverse,-  shiftLeft,-  shiftRight,-  filter,-  takeWhile,-  dropWhile,-  uncons,-  unsnoc,-  null,-  head,-  last,-  tail,-  init,+  LazyDefs.Deque,+  fromStrict,+  toStrict,+  LazyDefs.fromConsAndSnocLists,+  LazyDefs.cons,+  LazyDefs.snoc,+  LazyDefs.reverse,+  LazyDefs.shiftLeft,+  LazyDefs.shiftRight,+  LazyDefs.filter,+  LazyDefs.take,+  LazyDefs.drop,+  LazyDefs.takeWhile,+  LazyDefs.dropWhile,+  LazyDefs.uncons,+  LazyDefs.unsnoc,+  LazyDefs.null,+  LazyDefs.head,+  LazyDefs.last,+  LazyDefs.tail,+  LazyDefs.init, ) where -import Control.Monad (fail)-import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse, filter)-import qualified Data.List as List-import qualified Deque.Prelude as Prelude---- |--- Lazy double-ended queue (aka Dequeue or Deque) based on head-tail linked list.-data Deque a = Deque {-# UNPACK #-} ![a] {-# UNPACK #-} ![a]---- |--- /O(1)/.--- Construct from cons and snoc lists.-fromConsAndSnocLists :: [a] -> [a] -> Deque a-fromConsAndSnocLists consList snocList = Deque snocList consList---- |--- /O(n)/.--- Leave only the elements satisfying the predicate.-filter :: (a -> Bool) -> Deque a -> Deque a-filter predicate (Deque snocList consList) = Deque (List.filter predicate snocList) (List.filter predicate consList)---- |--- /O(n)/.--- Leave only the first elements satisfying the predicate.-takeWhile :: (a -> Bool) -> Deque a -> Deque a-takeWhile predicate (Deque snocList consList) = let-  newConsList = List.foldr-    (\ a nextState -> if predicate a-      then a : nextState-      else [])-    (List.takeWhile predicate (List.reverse snocList))-    consList-  in Deque [] newConsList---- |--- /O(n)/.--- Drop the first elements satisfying the predicate.-dropWhile :: (a -> Bool) -> Deque a -> Deque a-dropWhile predicate (Deque snocList consList) = let-  newConsList = List.dropWhile predicate consList-  in case newConsList of-    [] -> Deque [] (List.dropWhile predicate (List.reverse snocList))-    _ -> Deque snocList newConsList---- |--- /O(1)/, occasionally /O(n)/.--- Move the first element to the end.------ @--- λ toList . shiftLeft $ fromList [1,2,3]--- [2,3,1]--- @-shiftLeft :: Deque a -> Deque a-shiftLeft deque = maybe deque (uncurry snoc) (uncons deque)---- |--- /O(1)/, occasionally /O(n)/.--- Move the last element to the beginning.------ @--- λ toList . shiftRight $ fromList [1,2,3]--- [3,1,2]--- @-shiftRight :: Deque a -> Deque a-shiftRight deque = maybe deque (uncurry cons) (unsnoc deque)---- |--- /O(1)/.--- Add element in the beginning.-cons :: a -> Deque a -> Deque a-cons a (Deque snocList consList) = Deque snocList (a : consList)---- |--- /O(1)/.--- Add element in the ending.-snoc :: a -> Deque a -> Deque a-snoc a (Deque snocList consList) = Deque (a : snocList) consList---- |--- /O(1)/, occasionally /O(n)/.--- Get the first element and deque without it if it's not empty.-uncons :: Deque a -> Maybe (a, Deque a)-uncons (Deque snocList consList) = case consList of-  head : tail -> Just (head, Deque snocList tail)-  _ -> case List.reverse snocList of-    head : tail -> Just (head, Deque [] tail)-    _ -> Nothing---- |--- /O(1)/, occasionally /O(n)/.--- Get the last element and deque without it if it's not empty.-unsnoc :: Deque a -> Maybe (a, Deque a)-unsnoc (Deque snocList consList) = case snocList of-  head : tail -> Just (head, Deque tail consList)-  _ -> case List.reverse consList of-    head : tail -> Just (head, Deque tail [])-    _ -> Nothing---- |--- /O(n)/.-prepend :: Deque a -> Deque a -> Deque a-prepend (Deque snocList1 consList1) (Deque snocList2 consList2) = Deque snocList3 consList3 where-  snocList3 = snocList2 ++ foldl' (flip (:)) snocList1 consList2-  consList3 = consList1---- |--- /O(1)/.--- Reverse the deque.-reverse :: Deque a -> Deque a-reverse (Deque snocList consList) = Deque consList snocList---- |--- /O(1)/. --- Check whether deque is empty.-null :: Deque a -> Bool-null (Deque snocList consList) = List.null snocList && List.null consList---- |--- /O(1)/, occasionally /O(n)/.--- Get the first element if deque is not empty.-head :: Deque a -> Maybe a-head = fmap fst . uncons---- |--- /O(1)/, occasionally /O(n)/.--- Keep all elements but the first one.--- --- In case of empty deque returns an empty deque.-tail :: Deque a -> Deque a-tail = fromMaybe <$> id <*> fmap snd . uncons---- |--- /O(1)/, occasionally /O(n)/.--- Keep all elements but the last one.--- --- In case of empty deque returns an empty deque.-init :: Deque a -> Deque a-init = fromMaybe <$> id <*> fmap snd . unsnoc---- |--- /O(1)/, occasionally /O(n)/.--- Get the last element if deque is not empty.-last :: Deque a -> Maybe a-last = fmap fst . unsnoc---instance Eq a => Eq (Deque a) where-  (==) a b = toList a == toList b--instance Show a => Show (Deque a) where-  show = showString "fromList " . show . toList--instance Semigroup (Deque a) where-  (<>) = prepend--instance Monoid (Deque a) where-  mempty =-    Deque [] []-  mappend =-    (<>)--instance Foldable Deque where-  foldr step init (Deque snocList consList) = foldr step (foldl' (flip step) init snocList) consList-  foldl' step init (Deque snocList consList) = foldr' (flip step) (foldl' step init consList) snocList--instance Traversable Deque where-  traverse f (Deque ss cs) =-    (\cs' ss' -> Deque (List.reverse ss') cs') <$> traverse f cs <*> traverse f (List.reverse ss)--deriving instance Functor Deque--instance Applicative Deque where-  pure a = Deque [] [a]-  fs <*> as = fromList (toList fs <*> toList as)--instance Monad Deque where-  return = pure-  m >>= f = fromList (toList m >>= toList . f)-  fail = const mempty--instance Alternative Deque where-  empty = mempty-  (<|>) = mappend--instance MonadPlus Deque where-  mzero = empty-  mplus = (<|>)+import Deque.Prelude+import qualified Deque.Lazy.Defs as LazyDefs+import qualified Deque.Strict.Defs as StrictDefs -instance MonadFail Deque where-  fail = const mempty+{-| Convert strict deque to lazy deque. -}+fromStrict :: StrictDefs.Deque a -> LazyDefs.Deque a+fromStrict (StrictDefs.Deque consList snocList) = LazyDefs.Deque (toList consList) (toList snocList) --- |--- /O(1)/.-instance IsList (Deque a) where-  type Item (Deque a) = a-  fromList = Deque []-  toList (Deque snocList consList) = consList <> List.reverse snocList-  +{-| Convert lazy deque to strict deque. -}+toStrict :: LazyDefs.Deque a -> StrictDefs.Deque a+toStrict (LazyDefs.Deque consList snocList) = StrictDefs.Deque (fromList consList) (fromList snocList)
+ library/Deque/Lazy/Defs.hs view
@@ -0,0 +1,243 @@+{-|+Definitions of lazy Deque.++The typical `toList` and `fromList` conversions are provided by means of+the `Foldable` and `IsList` instances.+-}+module Deque.Lazy.Defs+where++import Control.Monad (fail)+import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse, filter, take)+import qualified Data.List as List+import qualified Deque.Prelude as Prelude++-- |+-- Lazy double-ended queue (aka Dequeue or Deque) based on head-tail linked list.+data Deque a = Deque ![a] ![a]++-- |+-- /O(1)/.+-- Construct from cons and snoc lists.+fromConsAndSnocLists :: [a] -> [a] -> Deque a+fromConsAndSnocLists consList snocList = Deque consList snocList++-- |+-- /O(n)/.+-- Leave only the elements satisfying the predicate.+filter :: (a -> Bool) -> Deque a -> Deque a+filter predicate (Deque consList snocList) = Deque (List.filter predicate consList) (List.filter predicate snocList)++-- |+-- /O(n)/.+-- Leave only the specified amount of first elements.+take :: Int -> Deque a -> Deque a+take amount (Deque consList snocList) = let+  newConsList = let+    buildFromConsList amount = if amount > 0+      then \ case+        head : tail -> head : buildFromConsList (pred amount) tail+        _ -> buildFromSnocList amount (List.reverse snocList)+      else const []+    buildFromSnocList amount = if amount > 0+      then \ case+        head : tail -> head : buildFromSnocList (pred amount) tail+        _ -> []+      else const []+    in buildFromConsList amount consList+  in Deque newConsList []++-- |+-- /O(n)/.+-- Drop the specified amount of first elements.+drop :: Int -> Deque a -> Deque a+drop amount (Deque consList snocList) = let+  buildFromConsList amount = if amount > 0+    then \ case+      _ : tail -> buildFromConsList (pred amount) tail+      _ -> buildFromSnocList amount (List.reverse snocList)+    else \ tail -> Deque tail snocList+  buildFromSnocList amount = if amount > 0+    then \ case+      _ : tail -> buildFromSnocList (pred amount) tail+      _ -> Deque [] []+    else \ tail -> Deque tail []+  in buildFromConsList amount consList++-- |+-- /O(n)/.+-- Leave only the first elements satisfying the predicate.+takeWhile :: (a -> Bool) -> Deque a -> Deque a+takeWhile predicate (Deque consList snocList) = let+  newConsList = List.foldr+    (\ a nextState -> if predicate a+      then a : nextState+      else [])+    (List.takeWhile predicate (List.reverse snocList))+    consList+  in Deque newConsList []++-- |+-- /O(n)/.+-- Drop the first elements satisfying the predicate.+dropWhile :: (a -> Bool) -> Deque a -> Deque a+dropWhile predicate (Deque consList snocList) = let+  newConsList = List.dropWhile predicate consList+  in case newConsList of+    [] -> Deque (List.dropWhile predicate (List.reverse snocList)) []+    _ -> Deque newConsList snocList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Move the first element to the end.+--+-- @+-- λ toList . shiftLeft $ fromList [1,2,3]+-- [2,3,1]+-- @+shiftLeft :: Deque a -> Deque a+shiftLeft deque = maybe deque (uncurry snoc) (uncons deque)++-- |+-- /O(1)/, occasionally /O(n)/.+-- Move the last element to the beginning.+--+-- @+-- λ toList . shiftRight $ fromList [1,2,3]+-- [3,1,2]+-- @+shiftRight :: Deque a -> Deque a+shiftRight deque = maybe deque (uncurry cons) (unsnoc deque)++-- |+-- /O(1)/.+-- Add element in the beginning.+cons :: a -> Deque a -> Deque a+cons a (Deque consList snocList) = Deque (a : consList) snocList++-- |+-- /O(1)/.+-- Add element in the ending.+snoc :: a -> Deque a -> Deque a+snoc a (Deque consList snocList) = Deque consList (a : snocList)++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the first element and deque without it if it's not empty.+uncons :: Deque a -> Maybe (a, Deque a)+uncons (Deque consList snocList) = case consList of+  head : tail -> Just (head, Deque tail snocList)+  _ -> case List.reverse snocList of+    head : tail -> Just (head, Deque tail [])+    _ -> Nothing++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the last element and deque without it if it's not empty.+unsnoc :: Deque a -> Maybe (a, Deque a)+unsnoc (Deque consList snocList) = case snocList of+  head : tail -> Just (head, Deque consList tail)+  _ -> case List.reverse consList of+    head : tail -> Just (head, Deque [] tail)+    _ -> Nothing++-- |+-- /O(n)/.+prepend :: Deque a -> Deque a -> Deque a+prepend (Deque snocList1 consList1) (Deque snocList2 consList2) = Deque consList3 snocList3 where+  consList3 = consList1+  snocList3 = snocList2 ++ foldl' (flip (:)) snocList1 consList2++-- |+-- /O(1)/.+-- Reverse the deque.+reverse :: Deque a -> Deque a+reverse (Deque consList snocList) = Deque snocList consList++-- |+-- /O(1)/. +-- Check whether deque is empty.+null :: Deque a -> Bool+null (Deque consList snocList) = List.null snocList && List.null consList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the first element if deque is not empty.+head :: Deque a -> Maybe a+head = fmap fst . uncons++-- |+-- /O(1)/, occasionally /O(n)/.+-- Keep all elements but the first one.+-- +-- In case of empty deque returns an empty deque.+tail :: Deque a -> Deque a+tail = fromMaybe <$> id <*> fmap snd . uncons++-- |+-- /O(1)/, occasionally /O(n)/.+-- Keep all elements but the last one.+-- +-- In case of empty deque returns an empty deque.+init :: Deque a -> Deque a+init = fromMaybe <$> id <*> fmap snd . unsnoc++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the last element if deque is not empty.+last :: Deque a -> Maybe a+last = fmap fst . unsnoc+++instance Eq a => Eq (Deque a) where+  (==) a b = toList a == toList b++instance Show a => Show (Deque a) where+  show = show . toList++instance Semigroup (Deque a) where+  (<>) = prepend++instance Monoid (Deque a) where+  mempty =+    Deque [] []+  mappend =+    (<>)++instance Foldable Deque where+  foldr step init (Deque consList snocList) = foldr step (foldl' (flip step) init snocList) consList+  foldl' step init (Deque consList snocList) = foldr' (flip step) (foldl' step init consList) snocList++instance Traversable Deque where+  traverse f (Deque cs ss) =+    (\cs' ss' -> Deque cs' (List.reverse ss')) <$> traverse f cs <*> traverse f (List.reverse ss)++deriving instance Functor Deque++instance Applicative Deque where+  pure a = Deque [] [a]+  fs <*> as = fromList (toList fs <*> toList as)++instance Monad Deque where+  return = pure+  m >>= f = fromList (toList m >>= toList . f)+  fail = const mempty++instance Alternative Deque where+  empty = mempty+  (<|>) = mappend++instance MonadPlus Deque where+  mzero = empty+  mplus = (<|>)++instance MonadFail Deque where+  fail = const mempty++-- |+-- /O(1)/.+instance IsList (Deque a) where+  type Item (Deque a) = a+  fromList = flip Deque []+  toList (Deque consList snocList) = consList <> List.reverse snocList+  
+ library/Deque/Lazy/Reader.hs view
@@ -0,0 +1,162 @@+{-|+Lazy Deque API lifted to a Reader monad, \"mtl\"-style.+-}+module Deque.Lazy.Reader+where++import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse)+import Deque.Lazy (Deque)+import qualified Deque.Lazy as Deque+import qualified Deque.Prelude as Prelude+++{-|+/O(n)/.+Modify each element of the queue.+-}+map :: MonadReader (Deque a) m => (a -> b) -> m (Deque b)+map f = reader (fmap f)++{-|+/O(n)/.+Add elements to the begginning.+-}+prepend :: MonadReader (Deque a) m => Deque a -> m (Deque a)+prepend deque = reader (deque <>)++{-|+/O(n)/.+Add elements to the ending.+-}+append :: MonadReader (Deque a) m => Deque a -> m (Deque a)+append deque = reader (<> deque)++{-|+/O(1)/.+Add element in the beginning.+-}+cons :: MonadReader (Deque a) m => a -> m (Deque a)+cons a = reader (Deque.cons a)++{-|+/O(1)/.+Add element in the ending.+-}+snoc :: MonadReader (Deque a) m => a -> m (Deque a)+snoc a = reader (Deque.snoc a)++{-|+/O(1)/.+Reverse the deque.+-}+reverse :: MonadReader (Deque a) m => m (Deque a)+reverse = reader Deque.reverse++{-|+/O(1)/, occasionally /O(n)/.+Move the first element to the end.+-}+shiftLeft :: MonadReader (Deque a) m => m (Deque a)+shiftLeft = reader Deque.shiftLeft++{-|+/O(1)/, occasionally /O(n)/.+Move the last element to the beginning.+-}+shiftRight :: MonadReader (Deque a) m => m (Deque a)+shiftRight = reader Deque.shiftRight++{-|+/O(n)/.+Leave only the elements satisfying the predicate.+-}+filter :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+filter predicate = reader (Deque.filter predicate)++{-|+/O(n)/.+Leave only the specified amount of first elements.+-}+take :: MonadReader (Deque a) m => Int -> m (Deque a)+take = reader . Deque.take++{-|+/O(n)/.+Drop the specified amount of first elements.+-}+drop :: MonadReader (Deque a) m => Int -> m (Deque a)+drop = reader . Deque.drop++{-|+/O(n)/.+Leave only the first elements satisfying the predicate.+-}+takeWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+takeWhile predicate = reader (Deque.takeWhile predicate)++{-|+/O(n)/.+Drop the first elements satisfying the predicate.+-}+dropWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+dropWhile predicate = reader (Deque.dropWhile predicate)++{-|+/O(1)/, occasionally /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 = reader (\ deque -> case Deque.uncons deque of+  Nothing -> (Nothing, deque)+  Just (a, newDeque) -> (Just a, newDeque))++{-|+/O(1)/, occasionally /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 = reader (\ deque -> case Deque.unsnoc deque of+  Nothing -> (Nothing, deque)+  Just (a, newDeque) -> (Just a, newDeque))++{-|+/O(1)/. +Check whether deque is empty.+-}+null :: MonadReader (Deque a) m => m Bool+null = reader Deque.null++{-|+/O(1)/. +Check whether deque is empty.+-}+length :: MonadReader (Deque a) m => m Int+length = reader Prelude.length++{-|+/O(1)/, occasionally /O(n)/.+Get the first element if deque is not empty.+-}+head :: MonadReader (Deque a) m => m (Maybe a)+head = reader Deque.head++{-|+/O(1)/, occasionally /O(n)/.+Get the last element if deque is not empty.+-}+last :: MonadReader (Deque a) m => m (Maybe a)+last = reader Deque.last++{-|+/O(1)/, occasionally /O(n)/.+Keep all elements but the first one.+-}+tail :: MonadReader (Deque a) m => m (Deque a)+tail = reader Deque.tail++{-|+/O(1)/, occasionally /O(n)/.+Keep all elements but the last one.+-}+init :: MonadReader (Deque a) m => m (Deque a)+init = reader Deque.init
library/Deque/Lazy/State.hs view
@@ -75,6 +75,20 @@  {-| /O(n)/.+Leave only the specified amount of first elements.+-}+take :: MonadState (Deque a) m => Int -> m ()+take = modify . Deque.take++{-|+/O(n)/.+Drop the specified amount of first elements.+-}+drop :: MonadState (Deque a) m => Int -> m ()+drop = modify . Deque.drop++{-|+/O(n)/. Leave only the first elements satisfying the predicate. -} takeWhile :: MonadState (Deque a) m => (a -> Bool) -> m ()@@ -136,17 +150,13 @@ {-| /O(1)/, occasionally /O(n)/. Keep all elements but the first one.--In case of empty deque returns an empty deque. -}-tail :: MonadState (Deque a) m => m (Deque a)-tail = gets Deque.tail+tail :: MonadState (Deque a) m => m ()+tail = modify Deque.tail  {-| /O(1)/, occasionally /O(n)/. Keep all elements but the last one.--In case of empty deque returns an empty deque. -}-init :: MonadState (Deque a) m => m (Deque a)-init = gets Deque.init+init :: MonadState (Deque a) m => m ()+init = modify Deque.init
library/Deque/Prelude.hs view
@@ -74,5 +74,9 @@  -- mtl --------------------------import Control.Monad.State.Strict as Exports hiding (fail)+import Control.Monad.Cont.Class as Exports hiding (fail)+import Control.Monad.Error.Class as Exports hiding (Error(..), fail)+import Control.Monad.Reader.Class as Exports hiding (fail)+import Control.Monad.State.Class as Exports hiding (fail)+import Control.Monad.Writer.Class as Exports hiding (fail) 
library/Deque/Strict.hs view
@@ -6,225 +6,38 @@ -} module Deque.Strict (-  Deque,-  fromConsAndSnocLists,-  cons,-  snoc,-  reverse,-  shiftLeft,-  shiftRight,-  filter,-  takeWhile,-  dropWhile,-  uncons,-  unsnoc,-  null,-  head,-  last,-  tail,-  init,+  StrictDefs.Deque,+  fromLazy,+  toLazy,+  StrictDefs.fromConsAndSnocLists,+  StrictDefs.cons,+  StrictDefs.snoc,+  StrictDefs.reverse,+  StrictDefs.shiftLeft,+  StrictDefs.shiftRight,+  StrictDefs.filter,+  StrictDefs.take,+  StrictDefs.drop,+  StrictDefs.takeWhile,+  StrictDefs.dropWhile,+  StrictDefs.uncons,+  StrictDefs.unsnoc,+  StrictDefs.null,+  StrictDefs.head,+  StrictDefs.last,+  StrictDefs.tail,+  StrictDefs.init, ) where -import Control.Monad (fail)-import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse, filter)-import qualified StrictList---- |--- Strict double-ended queue (aka Dequeue or Deque) based on head-tail linked list.-data Deque a = Deque {-# UNPACK #-} !(StrictList.List a) {-# UNPACK #-} !(StrictList.List a)---- |--- /O(n)/.--- Construct from cons and snoc lists.-fromConsAndSnocLists :: [a] -> [a] -> Deque a-fromConsAndSnocLists consList snocList = Deque (fromList snocList) (fromList consList)---- |--- /O(1)/.--- Add element in the beginning.-cons :: a -> Deque a -> Deque a-cons a (Deque snocList consList) = Deque snocList (StrictList.Cons a consList)---- |--- /O(1)/.--- Add element in the ending.-snoc :: a -> Deque a -> Deque a-snoc a (Deque snocList consList) = Deque (StrictList.Cons a snocList) consList---- |--- /O(1)/.--- Reverse the deque.-reverse :: Deque a -> Deque a-reverse (Deque snocList consList) = Deque consList snocList---- |--- /O(1)/, occasionally /O(n)/.--- Move the first element to the end.------ @--- λ toList . shiftLeft $ fromList [1,2,3]--- [2,3,1]--- @-shiftLeft :: Deque a -> Deque a-shiftLeft deque = maybe deque (uncurry snoc) (uncons deque)---- |--- /O(1)/, occasionally /O(n)/.--- Move the last element to the beginning.------ @--- λ toList . shiftRight $ fromList [1,2,3]--- [3,1,2]--- @-shiftRight :: Deque a -> Deque a-shiftRight deque = maybe deque (uncurry cons) (unsnoc deque)---- |--- /O(n)/.--- Leave only the elements satisfying the predicate.-filter :: (a -> Bool) -> Deque a -> Deque a-filter predicate (Deque snocList consList) = let-  newConsList = StrictList.prependReversed-    (StrictList.filterReversed predicate consList)-    (StrictList.filterReversed predicate snocList)-  in Deque StrictList.Nil newConsList---- |--- /O(n)/.--- Leave only the first elements satisfying the predicate.-takeWhile :: (a -> Bool) -> Deque a -> Deque a-takeWhile predicate (Deque snocList consList) = let-  newConsList = foldr-    (\ a nextState -> if predicate a-      then StrictList.Cons a nextState-      else StrictList.Nil)-    (StrictList.takeWhileFromEnding predicate snocList)-    consList-  in Deque StrictList.Nil newConsList---- |--- /O(n)/.--- Drop the first elements satisfying the predicate.-dropWhile :: (a -> Bool) -> Deque a -> Deque a-dropWhile predicate (Deque snocList consList) = let-  newConsList = StrictList.dropWhile predicate consList-  in case newConsList of-    StrictList.Nil -> Deque StrictList.Nil (StrictList.dropWhileFromEnding predicate snocList)-    _ -> Deque snocList newConsList---- |--- /O(1)/, occasionally /O(n)/.--- Get the first element and deque without it if it's not empty.-uncons :: Deque a -> Maybe (a, Deque a)-uncons (Deque snocList consList) = case consList of-  StrictList.Cons head tail -> Just (head, Deque snocList tail)-  _ -> case StrictList.reverse snocList of-    StrictList.Cons head tail -> Just (head, Deque StrictList.Nil tail)-    _ -> Nothing---- |--- /O(1)/, occasionally /O(n)/.--- Get the last element and deque without it if it's not empty.-unsnoc :: Deque a -> Maybe (a, Deque a)-unsnoc (Deque snocList consList) = case snocList of-  StrictList.Cons head tail -> Just (head, Deque tail consList)-  _ -> case StrictList.reverse consList of-    StrictList.Cons head tail -> Just (head, Deque tail StrictList.Nil)-    _ -> Nothing---- |--- /O(1)/. --- Check whether deque is empty.-null :: Deque a -> Bool-null = \ case-  Deque StrictList.Nil StrictList.Nil -> True-  _ -> False---- |--- /O(1)/, occasionally /O(n)/.--- Get the first element if deque is not empty.-head :: Deque a -> Maybe a-head (Deque snocList consList) = case consList of-  StrictList.Cons head _ -> Just head-  _ -> StrictList.last snocList---- |--- /O(1)/, occasionally /O(n)/.--- Get the last element if deque is not empty.-last :: Deque a -> Maybe a-last (Deque snocList consList) = case snocList of-  StrictList.Cons head _ -> Just head-  _ -> StrictList.last consList---- |--- /O(1)/, occasionally /O(n)/.--- Keep all elements but the first one.--- --- In case of empty deque returns an empty deque.-tail :: Deque a -> Deque a-tail (Deque snocList consList) = case consList of-  StrictList.Nil -> Deque StrictList.Nil (StrictList.initReversed snocList)-  _ -> Deque snocList (StrictList.tail consList)---- |--- /O(1)/, occasionally /O(n)/.--- Keep all elements but the last one.--- --- In case of empty deque returns an empty deque.-init :: Deque a -> Deque a-init (Deque snocList consList) = case snocList of-  StrictList.Nil -> Deque (StrictList.initReversed consList) StrictList.Nil-  _ -> Deque (StrictList.tail snocList) consList---instance Eq a => Eq (Deque a) where-  (==) a b = toList a == toList b--instance Show a => Show (Deque a) where-  show = showString "fromList " . show . toList--instance IsList (Deque a) where-  type Item (Deque a) = a-  fromList list = Deque (StrictList.fromListReversed list) StrictList.Nil-  toList (Deque snocList consList) = foldr (:) (toList (StrictList.reverse snocList)) consList--instance Semigroup (Deque a) where-  (<>) (Deque snocList1 consList1) (Deque snocList2 consList2) = let-    snocList3 = snocList2-    consList3 = consList1 <> StrictList.prependReversed snocList1 consList2-    in Deque snocList3 consList3--instance Monoid (Deque a) where-  mempty = Deque StrictList.Nil StrictList.Nil-  mappend = (<>)--deriving instance Functor Deque--instance Foldable Deque where-  foldr step init (Deque snocList consList) = foldr step (foldr step init (StrictList.reverse snocList)) consList-  foldl' step init (Deque snocList consList) = foldl' step (foldl' step init consList) (StrictList.reverse snocList)--instance Traversable Deque where-  traverse f (Deque ss cs) =-    (\cs' ss' -> Deque (StrictList.reverse ss') cs') <$> traverse f cs <*> traverse f (StrictList.reverse ss)--instance Applicative Deque where-  pure a = Deque StrictList.Nil (pure a)-  fs <*> as = fromList (toList fs <*> toList as)--instance Monad Deque where-  return = pure-  m >>= f = fromList (toList m >>= toList . f)-  fail = const mempty--instance Alternative Deque where-  empty = mempty-  (<|>) = mappend+import Deque.Prelude+import qualified Deque.Lazy.Defs as LazyDefs+import qualified Deque.Strict.Defs as StrictDefs -instance MonadPlus Deque where-  mzero = empty-  mplus = (<|>)+{-| Convert lazy deque to strict deque. -}+fromLazy :: LazyDefs.Deque a -> StrictDefs.Deque a+fromLazy (LazyDefs.Deque consList snocList) = StrictDefs.Deque (fromList consList) (fromList snocList) -instance MonadFail Deque where-  fail = const mempty+{-| Convert strict deque to lazy deque. -}+toLazy :: StrictDefs.Deque a -> LazyDefs.Deque a+toLazy (StrictDefs.Deque consList snocList) = LazyDefs.Deque (toList consList) (toList snocList)
+ library/Deque/Strict/Defs.hs view
@@ -0,0 +1,247 @@+{-|+Definitions of strict Deque.++The typical `toList` and `fromList` conversions are provided by means of+the `Foldable` and `IsList` instances.+-}+module Deque.Strict.Defs+where++import Control.Monad (fail)+import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse, filter, take)+import qualified StrictList++-- |+-- Strict double-ended queue (aka Dequeue or Deque) based on head-tail linked list.+data Deque a = Deque !(StrictList.List a) !(StrictList.List a)++-- |+-- /O(n)/.+-- Construct from cons and snoc lists.+fromConsAndSnocLists :: [a] -> [a] -> Deque a+fromConsAndSnocLists consList snocList = Deque (fromList consList) (fromList snocList)++-- |+-- /O(1)/.+-- Add element in the beginning.+cons :: a -> Deque a -> Deque a+cons a (Deque consList snocList) = Deque (StrictList.Cons a consList) snocList++-- |+-- /O(1)/.+-- Add element in the ending.+snoc :: a -> Deque a -> Deque a+snoc a (Deque consList snocList) = Deque consList (StrictList.Cons a snocList)++-- |+-- /O(1)/.+-- Reverse the deque.+reverse :: Deque a -> Deque a+reverse (Deque consList snocList) = Deque snocList consList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Move the first element to the end.+--+-- @+-- λ toList . shiftLeft $ fromList [1,2,3]+-- [2,3,1]+-- @+shiftLeft :: Deque a -> Deque a+shiftLeft deque = maybe deque (uncurry snoc) (uncons deque)++-- |+-- /O(1)/, occasionally /O(n)/.+-- Move the last element to the beginning.+--+-- @+-- λ toList . shiftRight $ fromList [1,2,3]+-- [3,1,2]+-- @+shiftRight :: Deque a -> Deque a+shiftRight deque = maybe deque (uncurry cons) (unsnoc deque)++-- |+-- /O(n)/.+-- Leave only the elements satisfying the predicate.+filter :: (a -> Bool) -> Deque a -> Deque a+filter predicate (Deque consList snocList) = let+  newConsList = StrictList.prependReversed+    (StrictList.filterReversed predicate consList)+    (StrictList.filterReversed predicate snocList)+  in Deque newConsList StrictList.Nil++-- |+-- /O(n)/.+-- Leave only the specified amount of first elements.+take :: Int -> Deque a -> Deque a+take amount (Deque consList snocList) = let+  newSnocList = let+    buildFromConsList amount !list = if amount > 0+      then \ case+        StrictList.Cons head tail -> buildFromConsList (pred amount) (StrictList.Cons head list) tail+        _ -> buildFromSnocList amount list (StrictList.reverse snocList)+      else const list+    buildFromSnocList amount !list = if amount > 0+      then \ case+        StrictList.Cons head tail -> buildFromSnocList (pred amount) (StrictList.Cons head list) tail+        _ -> list+      else const list+    in buildFromConsList amount StrictList.Nil consList+  in Deque StrictList.Nil newSnocList++-- |+-- /O(n)/.+-- Drop the specified amount of first elements.+drop :: Int -> Deque a -> Deque a+drop amount (Deque consList snocList) = let+  buildFromConsList amount = if amount > 0+    then \ case+      StrictList.Cons _ tail -> buildFromConsList (pred amount) tail+      _ -> buildFromSnocList amount (StrictList.reverse snocList)+    else \ tail -> Deque tail snocList+  buildFromSnocList amount = if amount > 0+    then \ case+      StrictList.Cons _ tail -> buildFromSnocList (pred amount) tail+      _ -> Deque StrictList.Nil StrictList.Nil+    else \ tail -> Deque tail StrictList.Nil+  in buildFromConsList amount consList++-- |+-- /O(n)/.+-- Leave only the first elements satisfying the predicate.+takeWhile :: (a -> Bool) -> Deque a -> Deque a+takeWhile predicate (Deque consList snocList) = let+  newConsList = foldr+    (\ a nextState -> if predicate a+      then StrictList.Cons a nextState+      else StrictList.Nil)+    (StrictList.takeWhileFromEnding predicate snocList)+    consList+  in Deque newConsList StrictList.Nil++-- |+-- /O(n)/.+-- Drop the first elements satisfying the predicate.+dropWhile :: (a -> Bool) -> Deque a -> Deque a+dropWhile predicate (Deque consList snocList) = let+  newConsList = StrictList.dropWhile predicate consList+  in case newConsList of+    StrictList.Nil -> Deque (StrictList.dropWhileFromEnding predicate snocList) StrictList.Nil+    _ -> Deque newConsList snocList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the first element and deque without it if it's not empty.+uncons :: Deque a -> Maybe (a, Deque a)+uncons (Deque consList snocList) = case consList of+  StrictList.Cons head tail -> Just (head, Deque tail snocList)+  _ -> case StrictList.reverse snocList of+    StrictList.Cons head tail -> Just (head, Deque tail StrictList.Nil)+    _ -> Nothing++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the last element and deque without it if it's not empty.+unsnoc :: Deque a -> Maybe (a, Deque a)+unsnoc (Deque consList snocList) = case snocList of+  StrictList.Cons head tail -> Just (head, Deque consList tail)+  _ -> case StrictList.reverse consList of+    StrictList.Cons head tail -> Just (head, Deque StrictList.Nil tail)+    _ -> Nothing++-- |+-- /O(1)/. +-- Check whether deque is empty.+null :: Deque a -> Bool+null = \ case+  Deque StrictList.Nil StrictList.Nil -> True+  _ -> False++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the first element if deque is not empty.+head :: Deque a -> Maybe a+head (Deque consList snocList) = case consList of+  StrictList.Cons head _ -> Just head+  _ -> StrictList.last snocList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Get the last element if deque is not empty.+last :: Deque a -> Maybe a+last (Deque consList snocList) = case snocList of+  StrictList.Cons head _ -> Just head+  _ -> StrictList.last consList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Keep all elements but the first one.+-- +-- In case of empty deque returns an empty deque.+tail :: Deque a -> Deque a+tail (Deque consList snocList) = case consList of+  StrictList.Nil -> Deque (StrictList.initReversed snocList) StrictList.Nil+  _ -> Deque (StrictList.tail consList) snocList++-- |+-- /O(1)/, occasionally /O(n)/.+-- Keep all elements but the last one.+-- +-- In case of empty deque returns an empty deque.+init :: Deque a -> Deque a+init (Deque consList snocList) = case snocList of+  StrictList.Nil -> Deque StrictList.Nil (StrictList.initReversed consList)+  _ -> Deque consList (StrictList.tail snocList)+++instance Eq a => Eq (Deque a) where+  (==) a b = toList a == toList b++instance Show a => Show (Deque a) where+  show = show . toList++instance IsList (Deque a) where+  type Item (Deque a) = a+  fromList list = Deque StrictList.Nil (StrictList.fromListReversed list)+  toList (Deque consList snocList) = foldr (:) (toList (StrictList.reverse snocList)) consList++instance Semigroup (Deque a) where+  (<>) (Deque snocList1 consList1) (Deque snocList2 consList2) = let+    consList3 = consList1 <> StrictList.prependReversed snocList1 consList2+    snocList3 = snocList2+    in Deque consList3 snocList3++instance Monoid (Deque a) where+  mempty = Deque StrictList.Nil StrictList.Nil+  mappend = (<>)++deriving instance Functor Deque++instance Foldable Deque where+  foldr step init (Deque consList snocList) = foldr step (foldr step init (StrictList.reverse snocList)) consList+  foldl' step init (Deque consList snocList) = foldl' step (foldl' step init consList) (StrictList.reverse snocList)++instance Traversable Deque where+  traverse f (Deque cs ss) =+    (\cs' ss' -> Deque cs' (StrictList.reverse ss')) <$> traverse f cs <*> traverse f (StrictList.reverse ss)++instance Applicative Deque where+  pure a = Deque (pure a) StrictList.Nil+  fs <*> as = fromList (toList fs <*> toList as)++instance Monad Deque where+  return = pure+  m >>= f = fromList (toList m >>= toList . f)+  fail = const mempty++instance Alternative Deque where+  empty = mempty+  (<|>) = mappend++instance MonadPlus Deque where+  mzero = empty+  mplus = (<|>)++instance MonadFail Deque where+  fail = const mempty
+ library/Deque/Strict/Reader.hs view
@@ -0,0 +1,162 @@+{-|+Strict Deque API lifted to a Reader monad, \"mtl\"-style.+-}+module Deque.Strict.Reader+where++import Deque.Prelude hiding (tail, init, last, head, null, dropWhile, takeWhile, reverse)+import Deque.Strict (Deque)+import qualified Deque.Strict as Deque+import qualified Deque.Prelude as Prelude+++{-|+/O(n)/.+Modify each element of the queue.+-}+map :: MonadReader (Deque a) m => (a -> b) -> m (Deque b)+map f = reader (fmap f)++{-|+/O(n)/.+Add elements to the begginning.+-}+prepend :: MonadReader (Deque a) m => Deque a -> m (Deque a)+prepend deque = reader (deque <>)++{-|+/O(n)/.+Add elements to the ending.+-}+append :: MonadReader (Deque a) m => Deque a -> m (Deque a)+append deque = reader (<> deque)++{-|+/O(1)/.+Add element in the beginning.+-}+cons :: MonadReader (Deque a) m => a -> m (Deque a)+cons a = reader (Deque.cons a)++{-|+/O(1)/.+Add element in the ending.+-}+snoc :: MonadReader (Deque a) m => a -> m (Deque a)+snoc a = reader (Deque.snoc a)++{-|+/O(1)/.+Reverse the deque.+-}+reverse :: MonadReader (Deque a) m => m (Deque a)+reverse = reader Deque.reverse++{-|+/O(1)/, occasionally /O(n)/.+Move the first element to the end.+-}+shiftLeft :: MonadReader (Deque a) m => m (Deque a)+shiftLeft = reader Deque.shiftLeft++{-|+/O(1)/, occasionally /O(n)/.+Move the last element to the beginning.+-}+shiftRight :: MonadReader (Deque a) m => m (Deque a)+shiftRight = reader Deque.shiftRight++{-|+/O(n)/.+Leave only the elements satisfying the predicate.+-}+filter :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+filter predicate = reader (Deque.filter predicate)++{-|+/O(n)/.+Leave only the specified amount of first elements.+-}+take :: MonadReader (Deque a) m => Int -> m (Deque a)+take = reader . Deque.take++{-|+/O(n)/.+Drop the specified amount of first elements.+-}+drop :: MonadReader (Deque a) m => Int -> m (Deque a)+drop = reader . Deque.drop++{-|+/O(n)/.+Leave only the first elements satisfying the predicate.+-}+takeWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+takeWhile predicate = reader (Deque.takeWhile predicate)++{-|+/O(n)/.+Drop the first elements satisfying the predicate.+-}+dropWhile :: MonadReader (Deque a) m => (a -> Bool) -> m (Deque a)+dropWhile predicate = reader (Deque.dropWhile predicate)++{-|+/O(1)/, occasionally /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 = reader (\ deque -> case Deque.uncons deque of+  Nothing -> (Nothing, deque)+  Just (a, newDeque) -> (Just a, newDeque))++{-|+/O(1)/, occasionally /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 = reader (\ deque -> case Deque.unsnoc deque of+  Nothing -> (Nothing, deque)+  Just (a, newDeque) -> (Just a, newDeque))++{-|+/O(1)/. +Check whether deque is empty.+-}+null :: MonadReader (Deque a) m => m Bool+null = reader Deque.null++{-|+/O(1)/. +Check whether deque is empty.+-}+length :: MonadReader (Deque a) m => m Int+length = reader Prelude.length++{-|+/O(1)/, occasionally /O(n)/.+Get the first element if deque is not empty.+-}+head :: MonadReader (Deque a) m => m (Maybe a)+head = reader Deque.head++{-|+/O(1)/, occasionally /O(n)/.+Get the last element if deque is not empty.+-}+last :: MonadReader (Deque a) m => m (Maybe a)+last = reader Deque.last++{-|+/O(1)/, occasionally /O(n)/.+Keep all elements but the first one.+-}+tail :: MonadReader (Deque a) m => m (Deque a)+tail = reader Deque.tail++{-|+/O(1)/, occasionally /O(n)/.+Keep all elements but the last one.+-}+init :: MonadReader (Deque a) m => m (Deque a)+init = reader Deque.init
library/Deque/Strict/State.hs view
@@ -75,6 +75,20 @@  {-| /O(n)/.+Leave only the specified amount of first elements.+-}+take :: MonadState (Deque a) m => Int -> m ()+take = modify . Deque.take++{-|+/O(n)/.+Drop the specified amount of first elements.+-}+drop :: MonadState (Deque a) m => Int -> m ()+drop = modify . Deque.drop++{-|+/O(n)/. Leave only the first elements satisfying the predicate. -} takeWhile :: MonadState (Deque a) m => (a -> Bool) -> m ()@@ -136,17 +150,13 @@ {-| /O(1)/, occasionally /O(n)/. Keep all elements but the first one.--In case of empty deque returns an empty deque. -}-tail :: MonadState (Deque a) m => m (Deque a)-tail = gets Deque.tail+tail :: MonadState (Deque a) m => m ()+tail = modify Deque.tail  {-| /O(1)/, occasionally /O(n)/. Keep all elements but the last one.--In case of empty deque returns an empty deque. -}-init :: MonadState (Deque a) m => m (Deque a)-init = gets Deque.init+init :: MonadState (Deque a) m => m ()+init = modify Deque.init
test/Main.hs view
@@ -1,6 +1,6 @@ module Main where -import Prelude hiding (toList)+import Prelude hiding (toList, choose) import GHC.Exts as Exports (IsList(..)) import Test.QuickCheck.Instances import Test.Tasty@@ -21,14 +21,35 @@     testImplementation "Strict"       toList fromList Strict.fromConsAndSnocLists       Strict.cons Strict.snoc Strict.reverse-      Strict.shiftLeft Strict.shiftRight Strict.filter Strict.takeWhile Strict.dropWhile+      Strict.shiftLeft Strict.shiftRight Strict.filter Strict.take Strict.drop Strict.takeWhile Strict.dropWhile       Strict.uncons Strict.unsnoc Strict.null Strict.head Strict.last Strict.tail Strict.init     ,     testImplementation "Lazy"       toList fromList Lazy.fromConsAndSnocLists       Lazy.cons Lazy.snoc Lazy.reverse-      Lazy.shiftLeft Lazy.shiftRight Lazy.filter Lazy.takeWhile Lazy.dropWhile+      Lazy.shiftLeft Lazy.shiftRight Lazy.filter Lazy.take Lazy.drop Lazy.takeWhile Lazy.dropWhile       Lazy.uncons Lazy.unsnoc Lazy.null Lazy.head Lazy.last Lazy.tail Lazy.init+    ,+    testGroup "Conversions" $+    [+      testGroup "Strict" $+      [+        testProperty "toLazy" $ forAll strictAndLazyDequeGen $ \ (strictDeque, lazyDeque) ->+        Strict.toLazy strictDeque === lazyDeque+        ,+        testProperty "fromLazy" $ forAll strictAndLazyDequeGen $ \ (strictDeque, lazyDeque) ->+        Strict.fromLazy lazyDeque === strictDeque+      ]+      ,+      testGroup "Lazy" $+      [+        testProperty "toStrict" $ forAll strictAndLazyDequeGen $ \ (strictDeque, lazyDeque) ->+        Lazy.toStrict lazyDeque === strictDeque+        ,+        testProperty "fromStrict" $ forAll strictAndLazyDequeGen $ \ (strictDeque, lazyDeque) ->+        Lazy.fromStrict strictDeque === lazyDeque+      ]+    ]   ]  {-|@@ -37,7 +58,7 @@ testImplementation name   (toList :: forall a. f a -> [a]) fromList fromConsAndSnocLists   cons snoc reverse-  shiftLeft shiftRight filter takeWhile dropWhile+  shiftLeft shiftRight filter take drop takeWhile dropWhile   uncons unsnoc null head last tail init =     testGroup ("Deque implementation: " <> name) $     [@@ -51,7 +72,7 @@       deque === fromList list       ,       testProperty "show" $ forAll dequeAndListGen $ \ (deque, list) ->-      show deque === "fromList " <> show list+      show deque === show list       ,       testProperty "cons" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \ (a, (deque, list)) ->       toList (cons a deque) === a : list@@ -73,6 +94,12 @@       testProperty "filter" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \ (predicate, (deque, list)) ->       toList (filter predicate deque) === List.filter predicate list       ,+      testProperty "take" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \ (amount, (deque, list)) ->+      toList (take amount deque) === List.take amount list+      ,+      testProperty "drop" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \ (amount, (deque, list)) ->+      toList (drop amount deque) === List.drop amount list+      ,       testProperty "takeWhile" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \ (predicate, (deque, list)) ->       toList (takeWhile predicate deque) === List.takeWhile predicate list       ,@@ -118,21 +145,44 @@       ,       testProperty "foldr" $ forAll dequeAndListGen $ \ (deque, list) ->       foldr (:) [] deque === foldr (:) [] list+      ,+      testProperty "traverse" $ forAll dequeAndListGen $ \ (deque, list) -> let+        fn x = if mod x 2 == 0 then Right x else Left x+        in fmap toList (traverse fn deque) === traverse fn list     ]     where-      listGen = arbitrary @[Word8]       dequeAndListGen = do         consList <- listGen         snocList <- listGen         return (fromConsAndSnocLists consList snocList, consList <> List.reverse snocList)-      predicateGen = do-        op <- elements [(>), (>=), (==), (<=), (<)]-        x <- arbitrary @Word8-        return (op x)+      kleisliGen :: Gen (Word8 -> [Word8])+      kleisliGen = do+        list <- listGen+        return $ \ x -> fmap (+ x) list -{-|-A workaround to satisfy QuickCheck's requirements,-when we need to generate a predicate.--}+sizedListGen maxSize = do+  length <- choose (0, maxSize)+  replicateM length (arbitrary @Word8)++listGen = arbitrary @[Word8]++predicateGen = do+  op <- elements [(>), (>=), (==), (<=), (<)]+  x <- arbitrary @Word8+  return (op x)++strictAndLazyDequeGen = do+  consList <- listGen+  snocList <- listGen+  return (Strict.fromConsAndSnocLists consList snocList, Lazy.fromConsAndSnocLists consList snocList)+++-- * Workarounds to satisfy QuickCheck's requirements,+-- when we need to generate a predicate.+-------------------------+ instance Show (Word8 -> Bool) where   show _ = "(Word8 -> Bool) function"++instance Show (Word8 -> [Word8]) where+  show _ = "(Word8 -> [Word8]) function"