├── cabal.project ├── .github └── workflows │ ├── on-push-to-master-or-pr.yaml │ ├── check.yaml │ └── on-push-to-release.yaml ├── LICENSE ├── library └── Deque │ ├── Lazy.hs │ ├── Strict.hs │ ├── Prelude.hs │ ├── Lazy │ ├── State.hs │ ├── Reader.hs │ └── Defs.hs │ └── Strict │ ├── State.hs │ ├── Reader.hs │ └── Defs.hs ├── deque.cabal └── test └── Main.hs /cabal.project: -------------------------------------------------------------------------------- 1 | packages: . 2 | -------------------------------------------------------------------------------- /.github/workflows/on-push-to-master-or-pr.yaml: -------------------------------------------------------------------------------- 1 | name: Compile, test and check the docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | 11 | format: 12 | uses: nikita-volkov/haskell-hackage-lib-github-actions-workflows/.github/workflows/format.yaml@v1 13 | secrets: inherit 14 | 15 | check: 16 | uses: ./.github/workflows/check.yaml 17 | secrets: inherit 18 | -------------------------------------------------------------------------------- /.github/workflows/check.yaml: -------------------------------------------------------------------------------- 1 | name: Compile, test and check the docs 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | 8 | check: 9 | 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | include: 14 | - ghc: 8.8.1 15 | ghc-options: "" 16 | ignore-haddock: true 17 | ignore-cabal-check: true 18 | - ghc: latest 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | 24 | - uses: nikita-volkov/build-and-test-cabal-package.github-action@v1 25 | with: 26 | ghc: ${{matrix.ghc}} 27 | ghc-options: ${{matrix.ghc-options}} 28 | ignore-haddock: ${{matrix.ignore-haddock}} 29 | ignore-cabal-check: ${{matrix.ignore-cabal-check}} 30 | -------------------------------------------------------------------------------- /.github/workflows/on-push-to-release.yaml: -------------------------------------------------------------------------------- 1 | name: Release the lib to Hackage 2 | 3 | on: 4 | push: 5 | branches: 6 | - supermajor 7 | - major 8 | - minor 9 | - patch 10 | 11 | concurrency: 12 | group: release 13 | cancel-in-progress: false 14 | 15 | jobs: 16 | 17 | format: 18 | uses: nikita-volkov/haskell-hackage-lib-github-actions-workflows/.github/workflows/format.yaml@v1 19 | secrets: inherit 20 | 21 | check: 22 | uses: ./.github/workflows/check.yaml 23 | secrets: inherit 24 | 25 | release: 26 | needs: 27 | - format 28 | - check 29 | uses: nikita-volkov/haskell-hackage-lib-github-actions-workflows/.github/workflows/release.yaml@v1 30 | secrets: inherit 31 | with: 32 | prefix-tag-with-v: false 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Nikita Volkov 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /library/Deque/Lazy.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Definitions of lazy Deque. 3 | -- 4 | -- The typical `toList` and `fromList` conversions are provided by means of 5 | -- the `Foldable` and `IsList` instances. 6 | module Deque.Lazy 7 | ( LazyDefs.Deque, 8 | fromStrict, 9 | toStrict, 10 | LazyDefs.fromConsAndSnocLists, 11 | LazyDefs.cons, 12 | LazyDefs.snoc, 13 | LazyDefs.reverse, 14 | LazyDefs.shiftLeft, 15 | LazyDefs.shiftRight, 16 | LazyDefs.filter, 17 | LazyDefs.take, 18 | LazyDefs.drop, 19 | LazyDefs.takeWhile, 20 | LazyDefs.dropWhile, 21 | LazyDefs.span, 22 | LazyDefs.uncons, 23 | LazyDefs.unsnoc, 24 | LazyDefs.null, 25 | LazyDefs.head, 26 | LazyDefs.last, 27 | LazyDefs.tail, 28 | LazyDefs.init, 29 | ) 30 | where 31 | 32 | import qualified Deque.Lazy.Defs as LazyDefs 33 | import Deque.Prelude 34 | import qualified Deque.Strict.Defs as StrictDefs 35 | 36 | -- | Convert strict deque to lazy deque. 37 | fromStrict :: StrictDefs.Deque a -> LazyDefs.Deque a 38 | fromStrict (StrictDefs.Deque consList snocList) = LazyDefs.Deque (toList consList) (toList snocList) 39 | 40 | -- | Convert lazy deque to strict deque. 41 | toStrict :: LazyDefs.Deque a -> StrictDefs.Deque a 42 | toStrict (LazyDefs.Deque consList snocList) = StrictDefs.Deque (fromList consList) (fromList snocList) 43 | -------------------------------------------------------------------------------- /library/Deque/Strict.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Definitions of strict Deque. 3 | -- 4 | -- The typical `toList` and `fromList` conversions are provided by means of 5 | -- the `Foldable` and `IsList` instances. 6 | module Deque.Strict 7 | ( StrictDefs.Deque, 8 | fromLazy, 9 | toLazy, 10 | StrictDefs.fromConsAndSnocLists, 11 | StrictDefs.cons, 12 | StrictDefs.snoc, 13 | StrictDefs.reverse, 14 | StrictDefs.shiftLeft, 15 | StrictDefs.shiftRight, 16 | StrictDefs.filter, 17 | StrictDefs.take, 18 | StrictDefs.drop, 19 | StrictDefs.takeWhile, 20 | StrictDefs.dropWhile, 21 | StrictDefs.span, 22 | StrictDefs.uncons, 23 | StrictDefs.unsnoc, 24 | StrictDefs.null, 25 | StrictDefs.head, 26 | StrictDefs.last, 27 | StrictDefs.tail, 28 | StrictDefs.init, 29 | ) 30 | where 31 | 32 | import qualified Deque.Lazy.Defs as LazyDefs 33 | import Deque.Prelude 34 | import qualified Deque.Strict.Defs as StrictDefs 35 | 36 | -- | Convert lazy deque to strict deque. 37 | fromLazy :: LazyDefs.Deque a -> StrictDefs.Deque a 38 | fromLazy (LazyDefs.Deque consList snocList) = StrictDefs.Deque (fromList consList) (fromList snocList) 39 | 40 | -- | Convert strict deque to lazy deque. 41 | toLazy :: StrictDefs.Deque a -> LazyDefs.Deque a 42 | toLazy (StrictDefs.Deque consList snocList) = LazyDefs.Deque (toList consList) (toList snocList) 43 | -------------------------------------------------------------------------------- /deque.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 3.0 2 | name: deque 3 | version: 0.4.4.2 4 | synopsis: Double-ended queues 5 | description: 6 | Strict and lazy implementations of Double-Ended Queue (aka Dequeue or Deque) 7 | based on head-tail linked list. 8 | 9 | category: Data 10 | homepage: https://github.com/nikita-volkov/deque 11 | bug-reports: https://github.com/nikita-volkov/deque/issues 12 | author: Nikita Volkov 13 | maintainer: Nikita Volkov 14 | copyright: (c) 2016, Nikita Volkov 15 | license: MIT 16 | license-file: LICENSE 17 | 18 | source-repository head 19 | type: git 20 | location: https://github.com/nikita-volkov/deque 21 | 22 | library 23 | hs-source-dirs: library 24 | default-extensions: 25 | NoImplicitPrelude 26 | BangPatterns 27 | DeriveDataTypeable 28 | DeriveFunctor 29 | DeriveGeneric 30 | DeriveTraversable 31 | FlexibleContexts 32 | FlexibleInstances 33 | LambdaCase 34 | RankNTypes 35 | ScopedTypeVariables 36 | StandaloneDeriving 37 | TypeApplications 38 | TypeFamilies 39 | 40 | ghc-options: -funbox-strict-fields 41 | default-language: Haskell2010 42 | exposed-modules: 43 | Deque.Lazy 44 | Deque.Lazy.Reader 45 | Deque.Lazy.State 46 | Deque.Strict 47 | Deque.Strict.Reader 48 | Deque.Strict.State 49 | 50 | other-modules: 51 | Deque.Lazy.Defs 52 | Deque.Prelude 53 | Deque.Strict.Defs 54 | 55 | build-depends: 56 | , base >=4.9 && <5 57 | , deepseq >=1.4.3 && <2 58 | , hashable >=1.2 && <2 59 | , mtl >=2.2 && <3 60 | , strict-list >=0.1.6 && <0.2 61 | 62 | test-suite test 63 | type: exitcode-stdio-1.0 64 | hs-source-dirs: test 65 | default-extensions: 66 | NoImplicitPrelude 67 | BangPatterns 68 | DeriveDataTypeable 69 | DeriveFunctor 70 | DeriveGeneric 71 | DeriveTraversable 72 | FlexibleContexts 73 | FlexibleInstances 74 | LambdaCase 75 | RankNTypes 76 | ScopedTypeVariables 77 | StandaloneDeriving 78 | TypeApplications 79 | TypeFamilies 80 | 81 | default-language: Haskell2010 82 | main-is: Main.hs 83 | build-depends: 84 | , deque 85 | , rerebase <2 86 | , tasty >=0.12 && <2 87 | , tasty-quickcheck >=0.9 && <0.12 88 | -------------------------------------------------------------------------------- /library/Deque/Prelude.hs: -------------------------------------------------------------------------------- 1 | module Deque.Prelude 2 | ( module Exports, 3 | ) 4 | where 5 | 6 | import Control.Applicative as Exports 7 | import Control.Arrow as Exports 8 | import Control.Category as Exports 9 | import Control.Concurrent as Exports 10 | import Control.DeepSeq as Exports 11 | import Control.Exception as Exports 12 | import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_) 13 | import Control.Monad.Cont.Class as Exports 14 | import Control.Monad.Error.Class as Exports 15 | import Control.Monad.Fail as Exports 16 | import Control.Monad.Fix as Exports hiding (fix) 17 | import Control.Monad.IO.Class as Exports 18 | import Control.Monad.Reader.Class as Exports 19 | import Control.Monad.ST as Exports 20 | import Control.Monad.State.Class as Exports 21 | import Control.Monad.Writer.Class as Exports 22 | import Data.Bits as Exports 23 | import Data.Bool as Exports 24 | import Data.Char as Exports 25 | import Data.Coerce as Exports 26 | import Data.Complex as Exports 27 | import Data.Data as Exports 28 | import Data.Dynamic as Exports 29 | import Data.Either as Exports 30 | import Data.Fixed as Exports 31 | import Data.Foldable as Exports hiding (toList) 32 | import Data.Function as Exports hiding (id, (.)) 33 | import Data.Functor as Exports hiding (unzip) 34 | import Data.Functor.Identity as Exports 35 | import Data.Hashable as Exports (Hashable) 36 | import Data.IORef as Exports 37 | import Data.Int as Exports 38 | import Data.Ix as Exports 39 | import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons, unsnoc) 40 | import Data.Maybe as Exports 41 | import Data.Monoid as Exports hiding (First (..), Last (..), (<>)) 42 | import Data.Ord as Exports 43 | import Data.Proxy as Exports 44 | import Data.Ratio as Exports 45 | import Data.STRef as Exports 46 | import Data.Semigroup as Exports 47 | import Data.String as Exports 48 | import Data.Traversable as Exports 49 | import Data.Tuple as Exports 50 | import Data.Unique as Exports 51 | import Data.Version as Exports 52 | import Data.Word as Exports 53 | import Debug.Trace as Exports 54 | import Foreign.ForeignPtr as Exports 55 | import Foreign.Ptr as Exports 56 | import Foreign.StablePtr as Exports 57 | import Foreign.Storable as Exports hiding (alignment, sizeOf) 58 | import GHC.Conc as Exports hiding (threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar) 59 | import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith) 60 | import GHC.Generics as Exports (Generic, Generic1) 61 | import GHC.IO.Exception as Exports 62 | import Numeric as Exports 63 | import System.Environment as Exports 64 | import System.Exit as Exports 65 | import System.IO as Exports 66 | import System.IO.Error as Exports 67 | import System.IO.Unsafe as Exports 68 | import System.Mem as Exports 69 | import System.Mem.StableName as Exports 70 | import System.Timeout as Exports 71 | import Text.Printf as Exports (hPrintf, printf) 72 | import Text.Read as Exports (Read (..), readEither, readMaybe) 73 | import Unsafe.Coerce as Exports 74 | import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.)) 75 | -------------------------------------------------------------------------------- /library/Deque/Lazy/State.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Lazy Deque API lifted to a State monad, \"mtl\"-style. 3 | module Deque.Lazy.State where 4 | 5 | import Deque.Lazy (Deque) 6 | import qualified Deque.Lazy as Deque 7 | import Deque.Prelude hiding (dropWhile, head, init, last, null, reverse, tail, takeWhile) 8 | import qualified Deque.Prelude as Prelude 9 | 10 | -- | 11 | -- \(\mathcal{O}(n)\). 12 | -- Modify each element of the queue. 13 | map :: (MonadState (Deque a) m) => (a -> a) -> m () 14 | map f = modify (fmap f) 15 | 16 | -- | 17 | -- \(\mathcal{O}(n)\). 18 | -- Add elements to the begginning. 19 | prepend :: (MonadState (Deque a) m) => Deque a -> m () 20 | prepend deque = modify (deque <>) 21 | 22 | -- | 23 | -- \(\mathcal{O}(n)\). 24 | -- Add elements to the ending. 25 | append :: (MonadState (Deque a) m) => Deque a -> m () 26 | append deque = modify (<> deque) 27 | 28 | -- | 29 | -- \(\mathcal{O}(1)\). 30 | -- Add element in the beginning. 31 | cons :: (MonadState (Deque a) m) => a -> m () 32 | cons a = modify (Deque.cons a) 33 | 34 | -- | 35 | -- \(\mathcal{O}(1)\). 36 | -- Add element in the ending. 37 | snoc :: (MonadState (Deque a) m) => a -> m () 38 | snoc a = modify (Deque.snoc a) 39 | 40 | -- | 41 | -- \(\mathcal{O}(1)\). 42 | -- Reverse the deque. 43 | reverse :: (MonadState (Deque a) m) => m () 44 | reverse = modify Deque.reverse 45 | 46 | -- | 47 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 48 | -- Move the first element to the end. 49 | shiftLeft :: (MonadState (Deque a) m) => m () 50 | shiftLeft = modify Deque.shiftLeft 51 | 52 | -- | 53 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 54 | -- Move the last element to the beginning. 55 | shiftRight :: (MonadState (Deque a) m) => m () 56 | shiftRight = modify Deque.shiftRight 57 | 58 | -- | 59 | -- \(\mathcal{O}(n)\). 60 | -- Leave only the elements satisfying the predicate. 61 | filter :: (MonadState (Deque a) m) => (a -> Bool) -> m () 62 | filter predicate = modify (Deque.filter predicate) 63 | 64 | -- | 65 | -- \(\mathcal{O}(n)\). 66 | -- Leave only the specified amount of first elements. 67 | take :: (MonadState (Deque a) m) => Int -> m () 68 | take = modify . Deque.take 69 | 70 | -- | 71 | -- \(\mathcal{O}(n)\). 72 | -- Drop the specified amount of first elements. 73 | drop :: (MonadState (Deque a) m) => Int -> m () 74 | drop = modify . Deque.drop 75 | 76 | -- | 77 | -- \(\mathcal{O}(n)\). 78 | -- Leave only the first elements satisfying the predicate. 79 | takeWhile :: (MonadState (Deque a) m) => (a -> Bool) -> m () 80 | takeWhile predicate = modify (Deque.takeWhile predicate) 81 | 82 | -- | 83 | -- \(\mathcal{O}(n)\). 84 | -- Drop the first elements satisfying the predicate. 85 | dropWhile :: (MonadState (Deque a) m) => (a -> Bool) -> m () 86 | dropWhile predicate = modify (Deque.dropWhile predicate) 87 | 88 | -- | 89 | -- \(\mathcal{O}(n)\). 90 | -- Return the first elements satisfying the predicate, removing them from the state. 91 | span :: (MonadState (Deque a) m) => (a -> Bool) -> m (Deque a) 92 | span predicate = state (Deque.span predicate) 93 | 94 | -- | 95 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 96 | -- Get the first element if deque is not empty, 97 | -- removing the element. 98 | uncons :: (MonadState (Deque a) m) => m (Maybe a) 99 | uncons = 100 | state 101 | ( \deque -> case Deque.uncons deque of 102 | Nothing -> (Nothing, deque) 103 | Just (a, newDeque) -> (Just a, newDeque) 104 | ) 105 | 106 | -- | 107 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 108 | -- Get the last element if deque is not empty, 109 | -- removing the element. 110 | unsnoc :: (MonadState (Deque a) m) => m (Maybe a) 111 | unsnoc = 112 | state 113 | ( \deque -> case Deque.unsnoc deque of 114 | Nothing -> (Nothing, deque) 115 | Just (a, newDeque) -> (Just a, newDeque) 116 | ) 117 | 118 | -- | 119 | -- \(\mathcal{O}(1)\). 120 | -- Check whether deque is empty. 121 | null :: (MonadState (Deque a) m) => m Bool 122 | null = gets Deque.null 123 | 124 | -- | 125 | -- \(\mathcal{O}(1)\). 126 | -- Check whether deque is empty. 127 | length :: (MonadState (Deque a) m) => m Int 128 | length = gets Prelude.length 129 | 130 | -- | 131 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 132 | -- Get the first element if deque is not empty. 133 | head :: (MonadState (Deque a) m) => m (Maybe a) 134 | head = gets Deque.head 135 | 136 | -- | 137 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 138 | -- Get the last element if deque is not empty. 139 | last :: (MonadState (Deque a) m) => m (Maybe a) 140 | last = gets Deque.last 141 | 142 | -- | 143 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 144 | -- Keep all elements but the first one. 145 | tail :: (MonadState (Deque a) m) => m () 146 | tail = modify Deque.tail 147 | 148 | -- | 149 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 150 | -- Keep all elements but the last one. 151 | init :: (MonadState (Deque a) m) => m () 152 | init = modify Deque.init 153 | -------------------------------------------------------------------------------- /library/Deque/Strict/State.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Strict Deque API lifted to a State monad, \"mtl\"-style. 3 | module Deque.Strict.State where 4 | 5 | import Deque.Prelude hiding (dropWhile, head, init, last, null, reverse, tail, takeWhile) 6 | import qualified Deque.Prelude as Prelude 7 | import Deque.Strict (Deque) 8 | import qualified Deque.Strict as Deque 9 | 10 | -- | 11 | -- \(\mathcal{O}(n)\). 12 | -- Modify each element of the queue. 13 | map :: (MonadState (Deque a) m) => (a -> a) -> m () 14 | map f = modify (fmap f) 15 | 16 | -- | 17 | -- \(\mathcal{O}(n)\). 18 | -- Add elements to the begginning. 19 | prepend :: (MonadState (Deque a) m) => Deque a -> m () 20 | prepend deque = modify (deque <>) 21 | 22 | -- | 23 | -- \(\mathcal{O}(n)\). 24 | -- Add elements to the ending. 25 | append :: (MonadState (Deque a) m) => Deque a -> m () 26 | append deque = modify (<> deque) 27 | 28 | -- | 29 | -- \(\mathcal{O}(1)\). 30 | -- Add element in the beginning. 31 | cons :: (MonadState (Deque a) m) => a -> m () 32 | cons a = modify (Deque.cons a) 33 | 34 | -- | 35 | -- \(\mathcal{O}(1)\). 36 | -- Add element in the ending. 37 | snoc :: (MonadState (Deque a) m) => a -> m () 38 | snoc a = modify (Deque.snoc a) 39 | 40 | -- | 41 | -- \(\mathcal{O}(1)\). 42 | -- Reverse the deque. 43 | reverse :: (MonadState (Deque a) m) => m () 44 | reverse = modify Deque.reverse 45 | 46 | -- | 47 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 48 | -- Move the first element to the end. 49 | shiftLeft :: (MonadState (Deque a) m) => m () 50 | shiftLeft = modify Deque.shiftLeft 51 | 52 | -- | 53 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 54 | -- Move the last element to the beginning. 55 | shiftRight :: (MonadState (Deque a) m) => m () 56 | shiftRight = modify Deque.shiftRight 57 | 58 | -- | 59 | -- \(\mathcal{O}(n)\). 60 | -- Leave only the elements satisfying the predicate. 61 | filter :: (MonadState (Deque a) m) => (a -> Bool) -> m () 62 | filter predicate = modify (Deque.filter predicate) 63 | 64 | -- | 65 | -- \(\mathcal{O}(n)\). 66 | -- Leave only the specified amount of first elements. 67 | take :: (MonadState (Deque a) m) => Int -> m () 68 | take = modify . Deque.take 69 | 70 | -- | 71 | -- \(\mathcal{O}(n)\). 72 | -- Drop the specified amount of first elements. 73 | drop :: (MonadState (Deque a) m) => Int -> m () 74 | drop = modify . Deque.drop 75 | 76 | -- | 77 | -- \(\mathcal{O}(n)\). 78 | -- Leave only the first elements satisfying the predicate. 79 | takeWhile :: (MonadState (Deque a) m) => (a -> Bool) -> m () 80 | takeWhile predicate = modify (Deque.takeWhile predicate) 81 | 82 | -- | 83 | -- \(\mathcal{O}(n)\). 84 | -- Drop the first elements satisfying the predicate. 85 | dropWhile :: (MonadState (Deque a) m) => (a -> Bool) -> m () 86 | dropWhile predicate = modify (Deque.dropWhile predicate) 87 | 88 | -- | 89 | -- \(\mathcal{O}(n)\). 90 | -- Return the first elements satisfying the predicate, removing them from the state. 91 | span :: (MonadState (Deque a) m) => (a -> Bool) -> m (Deque a) 92 | span predicate = state (Deque.span predicate) 93 | 94 | -- | 95 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 96 | -- Get the first element if deque is not empty, 97 | -- removing the element. 98 | uncons :: (MonadState (Deque a) m) => m (Maybe a) 99 | uncons = 100 | state 101 | ( \deque -> case Deque.uncons deque of 102 | Nothing -> (Nothing, deque) 103 | Just (a, newDeque) -> (Just a, newDeque) 104 | ) 105 | 106 | -- | 107 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 108 | -- Get the last element if deque is not empty, 109 | -- removing the element. 110 | unsnoc :: (MonadState (Deque a) m) => m (Maybe a) 111 | unsnoc = 112 | state 113 | ( \deque -> case Deque.unsnoc deque of 114 | Nothing -> (Nothing, deque) 115 | Just (a, newDeque) -> (Just a, newDeque) 116 | ) 117 | 118 | -- | 119 | -- \(\mathcal{O}(1)\). 120 | -- Check whether deque is empty. 121 | null :: (MonadState (Deque a) m) => m Bool 122 | null = gets Deque.null 123 | 124 | -- | 125 | -- \(\mathcal{O}(1)\). 126 | -- Check whether deque is empty. 127 | length :: (MonadState (Deque a) m) => m Int 128 | length = gets Prelude.length 129 | 130 | -- | 131 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 132 | -- Get the first element if deque is not empty. 133 | head :: (MonadState (Deque a) m) => m (Maybe a) 134 | head = gets Deque.head 135 | 136 | -- | 137 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 138 | -- Get the last element if deque is not empty. 139 | last :: (MonadState (Deque a) m) => m (Maybe a) 140 | last = gets Deque.last 141 | 142 | -- | 143 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 144 | -- Keep all elements but the first one. 145 | tail :: (MonadState (Deque a) m) => m () 146 | tail = modify Deque.tail 147 | 148 | -- | 149 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 150 | -- Keep all elements but the last one. 151 | init :: (MonadState (Deque a) m) => m () 152 | init = modify Deque.init 153 | -------------------------------------------------------------------------------- /library/Deque/Lazy/Reader.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Lazy Deque API lifted to a Reader monad, \"mtl\"-style. 3 | module Deque.Lazy.Reader where 4 | 5 | import Deque.Lazy (Deque) 6 | import qualified Deque.Lazy as Deque 7 | import Deque.Prelude hiding (dropWhile, head, init, last, null, reverse, tail, takeWhile) 8 | import qualified Deque.Prelude as Prelude 9 | 10 | -- | 11 | -- \(\mathcal{O}(n)\). 12 | -- Modify each element of the queue. 13 | map :: (MonadReader (Deque a) m) => (a -> b) -> m (Deque b) 14 | map f = reader (fmap f) 15 | 16 | -- | 17 | -- \(\mathcal{O}(n)\). 18 | -- Add elements to the begginning. 19 | prepend :: (MonadReader (Deque a) m) => Deque a -> m (Deque a) 20 | prepend deque = reader (deque <>) 21 | 22 | -- | 23 | -- \(\mathcal{O}(n)\). 24 | -- Add elements to the ending. 25 | append :: (MonadReader (Deque a) m) => Deque a -> m (Deque a) 26 | append deque = reader (<> deque) 27 | 28 | -- | 29 | -- \(\mathcal{O}(1)\). 30 | -- Add element in the beginning. 31 | cons :: (MonadReader (Deque a) m) => a -> m (Deque a) 32 | cons a = reader (Deque.cons a) 33 | 34 | -- | 35 | -- \(\mathcal{O}(1)\). 36 | -- Add element in the ending. 37 | snoc :: (MonadReader (Deque a) m) => a -> m (Deque a) 38 | snoc a = reader (Deque.snoc a) 39 | 40 | -- | 41 | -- \(\mathcal{O}(1)\). 42 | -- Reverse the deque. 43 | reverse :: (MonadReader (Deque a) m) => m (Deque a) 44 | reverse = reader Deque.reverse 45 | 46 | -- | 47 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 48 | -- Move the first element to the end. 49 | shiftLeft :: (MonadReader (Deque a) m) => m (Deque a) 50 | shiftLeft = reader Deque.shiftLeft 51 | 52 | -- | 53 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 54 | -- Move the last element to the beginning. 55 | shiftRight :: (MonadReader (Deque a) m) => m (Deque a) 56 | shiftRight = reader Deque.shiftRight 57 | 58 | -- | 59 | -- \(\mathcal{O}(n)\). 60 | -- Leave only the elements satisfying the predicate. 61 | filter :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 62 | filter predicate = reader (Deque.filter predicate) 63 | 64 | -- | 65 | -- \(\mathcal{O}(n)\). 66 | -- Leave only the specified amount of first elements. 67 | take :: (MonadReader (Deque a) m) => Int -> m (Deque a) 68 | take = reader . Deque.take 69 | 70 | -- | 71 | -- \(\mathcal{O}(n)\). 72 | -- Drop the specified amount of first elements. 73 | drop :: (MonadReader (Deque a) m) => Int -> m (Deque a) 74 | drop = reader . Deque.drop 75 | 76 | -- | 77 | -- \(\mathcal{O}(n)\). 78 | -- Leave only the first elements satisfying the predicate. 79 | takeWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 80 | takeWhile predicate = reader (Deque.takeWhile predicate) 81 | 82 | -- | 83 | -- \(\mathcal{O}(n)\). 84 | -- Drop the first elements satisfying the predicate. 85 | dropWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 86 | dropWhile predicate = reader (Deque.dropWhile predicate) 87 | 88 | -- | 89 | -- \(\mathcal{O}(n)\). 90 | -- Same as @(,) '<$>' `takeWhile` predicate '<*>' `dropWhile` predicate@. 91 | span :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a, Deque a) 92 | span predicate = reader (Deque.span predicate) 93 | 94 | -- | 95 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 96 | -- Get the first element and deque without it if it's not empty. 97 | uncons :: (MonadReader (Deque a) m) => m (Maybe a, Deque a) 98 | uncons = 99 | reader 100 | ( \deque -> case Deque.uncons deque of 101 | Nothing -> (Nothing, deque) 102 | Just (a, newDeque) -> (Just a, newDeque) 103 | ) 104 | 105 | -- | 106 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 107 | -- Get the last element and deque without it if it's not empty. 108 | unsnoc :: (MonadReader (Deque a) m) => m (Maybe a, Deque a) 109 | unsnoc = 110 | reader 111 | ( \deque -> case Deque.unsnoc deque of 112 | Nothing -> (Nothing, deque) 113 | Just (a, newDeque) -> (Just a, newDeque) 114 | ) 115 | 116 | -- | 117 | -- \(\mathcal{O}(1)\). 118 | -- Check whether deque is empty. 119 | null :: (MonadReader (Deque a) m) => m Bool 120 | null = reader Deque.null 121 | 122 | -- | 123 | -- \(\mathcal{O}(1)\). 124 | -- Check whether deque is empty. 125 | length :: (MonadReader (Deque a) m) => m Int 126 | length = reader Prelude.length 127 | 128 | -- | 129 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 130 | -- Get the first element if deque is not empty. 131 | head :: (MonadReader (Deque a) m) => m (Maybe a) 132 | head = reader Deque.head 133 | 134 | -- | 135 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 136 | -- Get the last element if deque is not empty. 137 | last :: (MonadReader (Deque a) m) => m (Maybe a) 138 | last = reader Deque.last 139 | 140 | -- | 141 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 142 | -- Keep all elements but the first one. 143 | tail :: (MonadReader (Deque a) m) => m (Deque a) 144 | tail = reader Deque.tail 145 | 146 | -- | 147 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 148 | -- Keep all elements but the last one. 149 | init :: (MonadReader (Deque a) m) => m (Deque a) 150 | init = reader Deque.init 151 | -------------------------------------------------------------------------------- /library/Deque/Strict/Reader.hs: -------------------------------------------------------------------------------- 1 | -- | 2 | -- Strict Deque API lifted to a Reader monad, \"mtl\"-style. 3 | module Deque.Strict.Reader where 4 | 5 | import Deque.Prelude hiding (dropWhile, head, init, last, null, reverse, tail, takeWhile) 6 | import qualified Deque.Prelude as Prelude 7 | import Deque.Strict (Deque) 8 | import qualified Deque.Strict as Deque 9 | 10 | -- | 11 | -- \(\mathcal{O}(n)\). 12 | -- Modify each element of the queue. 13 | map :: (MonadReader (Deque a) m) => (a -> b) -> m (Deque b) 14 | map f = reader (fmap f) 15 | 16 | -- | 17 | -- \(\mathcal{O}(n)\). 18 | -- Add elements to the begginning. 19 | prepend :: (MonadReader (Deque a) m) => Deque a -> m (Deque a) 20 | prepend deque = reader (deque <>) 21 | 22 | -- | 23 | -- \(\mathcal{O}(n)\). 24 | -- Add elements to the ending. 25 | append :: (MonadReader (Deque a) m) => Deque a -> m (Deque a) 26 | append deque = reader (<> deque) 27 | 28 | -- | 29 | -- \(\mathcal{O}(1)\). 30 | -- Add element in the beginning. 31 | cons :: (MonadReader (Deque a) m) => a -> m (Deque a) 32 | cons a = reader (Deque.cons a) 33 | 34 | -- | 35 | -- \(\mathcal{O}(1)\). 36 | -- Add element in the ending. 37 | snoc :: (MonadReader (Deque a) m) => a -> m (Deque a) 38 | snoc a = reader (Deque.snoc a) 39 | 40 | -- | 41 | -- \(\mathcal{O}(1)\). 42 | -- Reverse the deque. 43 | reverse :: (MonadReader (Deque a) m) => m (Deque a) 44 | reverse = reader Deque.reverse 45 | 46 | -- | 47 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 48 | -- Move the first element to the end. 49 | shiftLeft :: (MonadReader (Deque a) m) => m (Deque a) 50 | shiftLeft = reader Deque.shiftLeft 51 | 52 | -- | 53 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 54 | -- Move the last element to the beginning. 55 | shiftRight :: (MonadReader (Deque a) m) => m (Deque a) 56 | shiftRight = reader Deque.shiftRight 57 | 58 | -- | 59 | -- \(\mathcal{O}(n)\). 60 | -- Leave only the elements satisfying the predicate. 61 | filter :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 62 | filter predicate = reader (Deque.filter predicate) 63 | 64 | -- | 65 | -- \(\mathcal{O}(n)\). 66 | -- Leave only the specified amount of first elements. 67 | take :: (MonadReader (Deque a) m) => Int -> m (Deque a) 68 | take = reader . Deque.take 69 | 70 | -- | 71 | -- \(\mathcal{O}(n)\). 72 | -- Drop the specified amount of first elements. 73 | drop :: (MonadReader (Deque a) m) => Int -> m (Deque a) 74 | drop = reader . Deque.drop 75 | 76 | -- | 77 | -- \(\mathcal{O}(n)\). 78 | -- Leave only the first elements satisfying the predicate. 79 | takeWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 80 | takeWhile predicate = reader (Deque.takeWhile predicate) 81 | 82 | -- | 83 | -- \(\mathcal{O}(n)\). 84 | -- Drop the first elements satisfying the predicate. 85 | dropWhile :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a) 86 | dropWhile predicate = reader (Deque.dropWhile predicate) 87 | 88 | -- | 89 | -- \(\mathcal{O}(n)\). 90 | -- Same as @(,) '<$>' `takeWhile` predicate '<*>' `dropWhile` predicate@. 91 | span :: (MonadReader (Deque a) m) => (a -> Bool) -> m (Deque a, Deque a) 92 | span predicate = reader (Deque.span predicate) 93 | 94 | -- | 95 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 96 | -- Get the first element and deque without it if it's not empty. 97 | uncons :: (MonadReader (Deque a) m) => m (Maybe a, Deque a) 98 | uncons = 99 | reader 100 | ( \deque -> case Deque.uncons deque of 101 | Nothing -> (Nothing, deque) 102 | Just (a, newDeque) -> (Just a, newDeque) 103 | ) 104 | 105 | -- | 106 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 107 | -- Get the last element and deque without it if it's not empty. 108 | unsnoc :: (MonadReader (Deque a) m) => m (Maybe a, Deque a) 109 | unsnoc = 110 | reader 111 | ( \deque -> case Deque.unsnoc deque of 112 | Nothing -> (Nothing, deque) 113 | Just (a, newDeque) -> (Just a, newDeque) 114 | ) 115 | 116 | -- | 117 | -- \(\mathcal{O}(1)\). 118 | -- Check whether deque is empty. 119 | null :: (MonadReader (Deque a) m) => m Bool 120 | null = reader Deque.null 121 | 122 | -- | 123 | -- \(\mathcal{O}(1)\). 124 | -- Check whether deque is empty. 125 | length :: (MonadReader (Deque a) m) => m Int 126 | length = reader Prelude.length 127 | 128 | -- | 129 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 130 | -- Get the first element if deque is not empty. 131 | head :: (MonadReader (Deque a) m) => m (Maybe a) 132 | head = reader Deque.head 133 | 134 | -- | 135 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 136 | -- Get the last element if deque is not empty. 137 | last :: (MonadReader (Deque a) m) => m (Maybe a) 138 | last = reader Deque.last 139 | 140 | -- | 141 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 142 | -- Keep all elements but the first one. 143 | tail :: (MonadReader (Deque a) m) => m (Deque a) 144 | tail = reader Deque.tail 145 | 146 | -- | 147 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 148 | -- Keep all elements but the last one. 149 | init :: (MonadReader (Deque a) m) => m (Deque a) 150 | init = reader Deque.init 151 | -------------------------------------------------------------------------------- /test/Main.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans -Wno-missing-signatures #-} 2 | 3 | module Main where 4 | 5 | import qualified Data.List as List 6 | import qualified Deque.Lazy as Lazy 7 | import qualified Deque.Strict as Strict 8 | import GHC.Exts as Exports (IsList (..)) 9 | import Test.Tasty 10 | import Test.Tasty.QuickCheck 11 | import Prelude hiding (choose, toList) 12 | 13 | main = 14 | defaultMain 15 | $ testGroup "" 16 | $ [ testImplementation 17 | "Strict" 18 | toList 19 | fromList 20 | Strict.fromConsAndSnocLists 21 | Strict.cons 22 | Strict.snoc 23 | Strict.reverse 24 | Strict.shiftLeft 25 | Strict.shiftRight 26 | Strict.filter 27 | Strict.take 28 | Strict.drop 29 | Strict.takeWhile 30 | Strict.dropWhile 31 | Strict.span 32 | Strict.uncons 33 | Strict.unsnoc 34 | Strict.null 35 | Strict.head 36 | Strict.last 37 | Strict.tail 38 | Strict.init, 39 | testImplementation 40 | "Lazy" 41 | toList 42 | fromList 43 | Lazy.fromConsAndSnocLists 44 | Lazy.cons 45 | Lazy.snoc 46 | Lazy.reverse 47 | Lazy.shiftLeft 48 | Lazy.shiftRight 49 | Lazy.filter 50 | Lazy.take 51 | Lazy.drop 52 | Lazy.takeWhile 53 | Lazy.dropWhile 54 | Lazy.span 55 | Lazy.uncons 56 | Lazy.unsnoc 57 | Lazy.null 58 | Lazy.head 59 | Lazy.last 60 | Lazy.tail 61 | Lazy.init, 62 | testGroup "Conversions" 63 | $ [ testGroup "Strict" 64 | $ [ testProperty "toLazy" $ forAll strictAndLazyDequeGen $ \(strictDeque, lazyDeque) -> 65 | Strict.toLazy strictDeque === lazyDeque, 66 | testProperty "fromLazy" $ forAll strictAndLazyDequeGen $ \(strictDeque, lazyDeque) -> 67 | Strict.fromLazy lazyDeque === strictDeque 68 | ], 69 | testGroup "Lazy" 70 | $ [ testProperty "toStrict" $ forAll strictAndLazyDequeGen $ \(strictDeque, lazyDeque) -> 71 | Lazy.toStrict lazyDeque === strictDeque, 72 | testProperty "fromStrict" $ forAll strictAndLazyDequeGen $ \(strictDeque, lazyDeque) -> 73 | Lazy.fromStrict strictDeque === lazyDeque 74 | ] 75 | ] 76 | ] 77 | 78 | -- | 79 | -- Test group, which abstracts over the implementation of deque. 80 | testImplementation 81 | name 82 | (toList :: forall a. f a -> [a]) 83 | fromList 84 | fromConsAndSnocLists 85 | cons 86 | snoc 87 | reverse 88 | shiftLeft 89 | shiftRight 90 | filter 91 | take 92 | drop 93 | takeWhile 94 | dropWhile 95 | span 96 | uncons 97 | unsnoc 98 | null 99 | head 100 | last 101 | tail 102 | init = 103 | testGroup ("Deque implementation: " <> name) 104 | $ [ testProperty "toList" $ forAll dequeAndListGen $ \(deque, list) -> 105 | toList deque === list, 106 | testProperty "fromList" $ forAll listGen $ \list -> 107 | toList (fromList list) === list, 108 | testProperty "eq" $ forAll dequeAndListGen $ \(deque, list) -> 109 | deque === fromList list, 110 | testProperty "show" $ forAll dequeAndListGen $ \(deque, list) -> 111 | show deque === show list, 112 | testProperty "cons" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \(a, (deque, list)) -> 113 | toList (cons a deque) === a : list, 114 | testProperty "snoc" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \(a, (deque, list)) -> 115 | toList (snoc a deque) === list <> [a], 116 | testProperty "reverse" $ forAll dequeAndListGen $ \(deque, list) -> 117 | toList (reverse deque) === List.reverse list, 118 | testProperty "shiftLeft" $ forAll dequeAndListGen $ \(deque, list) -> 119 | toList (shiftLeft deque) === List.drop 1 list <> List.take 1 list, 120 | testProperty "shiftRight" $ forAll dequeAndListGen $ \(deque, list) -> 121 | toList (shiftRight deque) === case list of 122 | [] -> [] 123 | _ -> List.last list : List.init list, 124 | testProperty "filter" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \(predicate, (deque, list)) -> 125 | toList (filter predicate deque) === List.filter predicate list, 126 | testProperty "take" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \(amount, (deque, list)) -> 127 | toList (take amount deque) === List.take amount list, 128 | testProperty "drop" $ forAll ((,) <$> arbitrary <*> dequeAndListGen) $ \(amount, (deque, list)) -> 129 | toList (drop amount deque) === List.drop amount list, 130 | testProperty "takeWhile" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \(predicate, (deque, list)) -> 131 | toList (takeWhile predicate deque) === List.takeWhile predicate list, 132 | testProperty "dropWhile" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \(predicate, (deque, list)) -> 133 | toList (dropWhile predicate deque) === List.dropWhile predicate list, 134 | testProperty "span" $ forAll ((,) <$> predicateGen <*> dequeAndListGen) $ \(predicate, (deque, list)) -> 135 | bimap toList toList (span predicate deque) === List.span predicate list, 136 | testProperty "uncons" $ forAll dequeAndListGen $ \(deque, list) -> 137 | fmap (fmap toList) (uncons deque) === List.uncons list, 138 | testProperty "unsnoc" $ forAll dequeAndListGen $ \(deque, list) -> 139 | fmap (fmap toList) (unsnoc deque) === case list of 140 | [] -> Nothing 141 | _ -> Just (List.last list, List.init list), 142 | testProperty "null" $ forAll dequeAndListGen $ \(deque, list) -> 143 | null deque === List.null list, 144 | testProperty "head" $ forAll dequeAndListGen $ \(deque, list) -> 145 | head deque === case list of 146 | head : _ -> Just head 147 | _ -> Nothing, 148 | testProperty "last" $ forAll dequeAndListGen $ \(deque, list) -> 149 | last deque === case list of 150 | [] -> Nothing 151 | _ -> Just (List.last list), 152 | testProperty "tail" $ forAll dequeAndListGen $ \(deque, list) -> 153 | toList (tail deque) === case list of 154 | _ : tail -> tail 155 | _ -> [], 156 | testProperty "init" $ forAll dequeAndListGen $ \(deque, list) -> 157 | toList (init deque) === case list of 158 | [] -> [] 159 | _ -> List.init list, 160 | testProperty "<>" $ forAll ((,) <$> dequeAndListGen <*> dequeAndListGen) $ \((deque1, list1), (deque2, list2)) -> 161 | toList (deque1 <> deque2) === (list1 <> list2), 162 | testProperty "<*>" $ forAll ((,) <$> dequeAndListGen <*> dequeAndListGen) $ \((deque1, list1), (deque2, list2)) -> 163 | toList ((,) <$> deque1 <*> deque2) === ((,) <$> list1 <*> list2), 164 | testProperty ">>=" $ forAll ((,) <$> dequeAndListKleisliGen <*> dequeAndListGen) $ \((dequeK, listK), (deque, list)) -> 165 | toList (deque >>= dequeK) === (list >>= listK), 166 | testProperty "foldl'" $ forAll dequeAndListGen $ \(deque, list) -> 167 | foldl' (flip (:)) [] deque === foldl' (flip (:)) [] list, 168 | testProperty "foldr" $ forAll dequeAndListGen $ \(deque, list) -> 169 | foldr (:) [] deque === foldr (:) [] list, 170 | testProperty "traverse" $ forAll dequeAndListGen $ \(deque, list) -> 171 | let fn x = if mod x 2 == 0 then Right x else Left x 172 | in fmap toList (traverse fn deque) === traverse fn list 173 | ] 174 | where 175 | dequeAndListGen = do 176 | consList <- listGen 177 | snocList <- listGen 178 | return (fromConsAndSnocLists consList snocList, consList <> List.reverse snocList) 179 | dequeAndListKleisliGen = do 180 | list <- listGen 181 | let listK x = fmap (+ x) list 182 | dequeK = fromList . listK 183 | in return (dequeK, listK) 184 | 185 | sizedListGen maxSize = do 186 | length <- choose (0, maxSize) 187 | replicateM length (arbitrary @Word8) 188 | 189 | listGen = arbitrary @[Word8] 190 | 191 | predicateGen = do 192 | op <- elements [(>), (>=), (==), (<=), (<)] 193 | x <- arbitrary @Word8 194 | return (op x) 195 | 196 | strictAndLazyDequeGen = do 197 | consList <- listGen 198 | snocList <- listGen 199 | return (Strict.fromConsAndSnocLists consList snocList, Lazy.fromConsAndSnocLists consList snocList) 200 | 201 | -- Workarounds to satisfy QuickCheck's requirements, 202 | -- when we need to generate a predicate. 203 | ------------------------- 204 | 205 | instance Show (Word8 -> Bool) where 206 | show _ = "@(Word8 -> Bool)" 207 | 208 | instance Show (Word8 -> [Word8]) where 209 | show _ = "@(Word8 -> [Word8])" 210 | 211 | instance Show (Word8 -> Strict.Deque Word8) where 212 | show _ = "@(Word8 -> Deque Word8)" 213 | 214 | instance Show (Word8 -> Lazy.Deque Word8) where 215 | show _ = "@(Word8 -> Deque Word8)" 216 | -------------------------------------------------------------------------------- /library/Deque/Lazy/Defs.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | -- | 4 | -- Definitions of lazy Deque. 5 | -- 6 | -- The typical `toList` and `fromList` conversions are provided by means of 7 | -- the `Foldable` and `IsList` instances. 8 | module Deque.Lazy.Defs where 9 | 10 | import qualified Data.List as List 11 | import Deque.Prelude hiding (dropWhile, filter, head, init, last, null, reverse, tail, take, takeWhile) 12 | 13 | -- | 14 | -- Lazy double-ended queue (aka Dequeue or Deque) based on head-tail linked list. 15 | data Deque a = Deque ![a] ![a] 16 | 17 | -- | 18 | -- \(\mathcal{O}(1)\). 19 | -- Construct from cons and snoc lists. 20 | fromConsAndSnocLists :: [a] -> [a] -> Deque a 21 | fromConsAndSnocLists consList snocList = Deque consList snocList 22 | 23 | -- | 24 | -- \(\mathcal{O}(n)\). 25 | -- Leave only the elements satisfying the predicate. 26 | filter :: (a -> Bool) -> Deque a -> Deque a 27 | filter predicate (Deque consList snocList) = Deque (List.filter predicate consList) (List.filter predicate snocList) 28 | 29 | -- | 30 | -- \(\mathcal{O}(n)\). 31 | -- Leave only the specified amount of first elements. 32 | take :: Int -> Deque a -> Deque a 33 | take amount (Deque consList snocList) = 34 | let newConsList = 35 | let buildFromConsList amount = 36 | if amount > 0 37 | then \case 38 | head : tail -> head : buildFromConsList (pred amount) tail 39 | _ -> buildFromSnocList amount (List.reverse snocList) 40 | else const [] 41 | buildFromSnocList amount = 42 | if amount > 0 43 | then \case 44 | head : tail -> head : buildFromSnocList (pred amount) tail 45 | _ -> [] 46 | else const [] 47 | in buildFromConsList amount consList 48 | in Deque newConsList [] 49 | 50 | -- | 51 | -- \(\mathcal{O}(n)\). 52 | -- Drop the specified amount of first elements. 53 | drop :: Int -> Deque a -> Deque a 54 | drop amount (Deque consList snocList) = 55 | let buildFromConsList amount = 56 | if amount > 0 57 | then \case 58 | _ : tail -> buildFromConsList (pred amount) tail 59 | _ -> buildFromSnocList amount (List.reverse snocList) 60 | else \tail -> Deque tail snocList 61 | buildFromSnocList amount = 62 | if amount > 0 63 | then \case 64 | _ : tail -> buildFromSnocList (pred amount) tail 65 | _ -> Deque [] [] 66 | else \tail -> Deque tail [] 67 | in buildFromConsList amount consList 68 | 69 | -- | 70 | -- \(\mathcal{O}(n)\). 71 | -- Leave only the first elements satisfying the predicate. 72 | takeWhile :: (a -> Bool) -> Deque a -> Deque a 73 | takeWhile predicate (Deque consList snocList) = 74 | let newConsList = 75 | List.foldr 76 | ( \a nextState -> 77 | if predicate a 78 | then a : nextState 79 | else [] 80 | ) 81 | (List.takeWhile predicate (List.reverse snocList)) 82 | consList 83 | in Deque newConsList [] 84 | 85 | -- | 86 | -- \(\mathcal{O}(n)\). 87 | -- Drop the first elements satisfying the predicate. 88 | dropWhile :: (a -> Bool) -> Deque a -> Deque a 89 | dropWhile predicate (Deque consList snocList) = 90 | let newConsList = List.dropWhile predicate consList 91 | in case newConsList of 92 | [] -> Deque (List.dropWhile predicate (List.reverse snocList)) [] 93 | _ -> Deque newConsList snocList 94 | 95 | -- | 96 | -- \(\mathcal{O}(n)\). 97 | -- Perform `takeWhile` and `dropWhile` in a single operation. 98 | span :: (a -> Bool) -> Deque a -> (Deque a, Deque a) 99 | span predicate (Deque consList snocList) = case List.span predicate consList of 100 | (consPrefix, consSuffix) -> 101 | if List.null consSuffix 102 | then case List.span predicate (List.reverse snocList) of 103 | (snocPrefix, snocSuffix) -> 104 | let prefix = Deque (consPrefix <> snocPrefix) [] 105 | suffix = Deque snocSuffix [] 106 | in (prefix, suffix) 107 | else 108 | let prefix = Deque consPrefix [] 109 | suffix = Deque consSuffix snocList 110 | in (prefix, suffix) 111 | 112 | -- | 113 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 114 | -- Move the first element to the end. 115 | -- 116 | -- @ 117 | -- λ toList . shiftLeft $ fromList [1,2,3] 118 | -- [2,3,1] 119 | -- @ 120 | shiftLeft :: Deque a -> Deque a 121 | shiftLeft deque = maybe deque (uncurry snoc) (uncons deque) 122 | 123 | -- | 124 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 125 | -- Move the last element to the beginning. 126 | -- 127 | -- @ 128 | -- λ toList . shiftRight $ fromList [1,2,3] 129 | -- [3,1,2] 130 | -- @ 131 | shiftRight :: Deque a -> Deque a 132 | shiftRight deque = maybe deque (uncurry cons) (unsnoc deque) 133 | 134 | -- | 135 | -- \(\mathcal{O}(1)\). 136 | -- Add element in the beginning. 137 | cons :: a -> Deque a -> Deque a 138 | cons a (Deque consList snocList) = Deque (a : consList) snocList 139 | 140 | -- | 141 | -- \(\mathcal{O}(1)\). 142 | -- Add element in the ending. 143 | snoc :: a -> Deque a -> Deque a 144 | snoc a (Deque consList snocList) = Deque consList (a : snocList) 145 | 146 | -- | 147 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 148 | -- Get the first element and deque without it if it's not empty. 149 | uncons :: Deque a -> Maybe (a, Deque a) 150 | uncons (Deque consList snocList) = case consList of 151 | head : tail -> Just (head, Deque tail snocList) 152 | _ -> case List.reverse snocList of 153 | head : tail -> Just (head, Deque tail []) 154 | _ -> Nothing 155 | 156 | -- | 157 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 158 | -- Get the last element and deque without it if it's not empty. 159 | unsnoc :: Deque a -> Maybe (a, Deque a) 160 | unsnoc (Deque consList snocList) = case snocList of 161 | head : tail -> Just (head, Deque consList tail) 162 | _ -> case List.reverse consList of 163 | head : tail -> Just (head, Deque [] tail) 164 | _ -> Nothing 165 | 166 | -- | 167 | -- \(\mathcal{O}(n)\). 168 | prepend :: Deque a -> Deque a -> Deque a 169 | prepend (Deque consList1 snocList1) (Deque consList2 snocList2) = 170 | let consList = consList1 171 | snocList = snocList2 ++ foldl' (flip (:)) snocList1 consList2 172 | in Deque consList snocList 173 | 174 | -- | 175 | -- \(\mathcal{O}(1)\). 176 | -- Reverse the deque. 177 | reverse :: Deque a -> Deque a 178 | reverse (Deque consList snocList) = Deque snocList consList 179 | 180 | -- | 181 | -- \(\mathcal{O}(1)\). 182 | -- Check whether deque is empty. 183 | null :: Deque a -> Bool 184 | null (Deque consList snocList) = List.null snocList && List.null consList 185 | 186 | -- | 187 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 188 | -- Get the first element if deque is not empty. 189 | head :: Deque a -> Maybe a 190 | head = fmap fst . uncons 191 | 192 | -- | 193 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 194 | -- Keep all elements but the first one. 195 | -- 196 | -- In case of empty deque returns an empty deque. 197 | tail :: Deque a -> Deque a 198 | tail = fromMaybe <$> id <*> fmap snd . uncons 199 | 200 | -- | 201 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 202 | -- Keep all elements but the last one. 203 | -- 204 | -- In case of empty deque returns an empty deque. 205 | init :: Deque a -> Deque a 206 | init = fromMaybe <$> id <*> fmap snd . unsnoc 207 | 208 | -- | 209 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 210 | -- Get the last element if deque is not empty. 211 | last :: Deque a -> Maybe a 212 | last = fmap fst . unsnoc 213 | 214 | instance (Eq a) => Eq (Deque a) where 215 | (==) a b = toList a == toList b 216 | 217 | instance (Show a) => Show (Deque a) where 218 | show = show . toList 219 | 220 | instance Semigroup (Deque a) where 221 | (<>) = prepend 222 | 223 | instance Monoid (Deque a) where 224 | mempty = 225 | Deque [] [] 226 | mappend = 227 | (<>) 228 | 229 | instance Foldable Deque where 230 | foldr step init (Deque consList snocList) = foldr step (foldl' (flip step) init snocList) consList 231 | foldl' step init (Deque consList snocList) = foldr' (flip step) (foldl' step init consList) snocList 232 | 233 | instance Traversable Deque where 234 | traverse f (Deque cs ss) = 235 | (\cs' ss' -> Deque cs' (List.reverse ss')) <$> traverse f cs <*> traverse f (List.reverse ss) 236 | 237 | deriving instance Functor Deque 238 | 239 | instance Applicative Deque where 240 | pure a = Deque [] [a] 241 | (<*>) (Deque fnConsList fnSnocList) (Deque argConsList argSnocList) = 242 | let consList = 243 | let fnStep fn resultConsList = 244 | let argStep arg = (:) (fn arg) 245 | in foldr argStep (foldr argStep resultConsList (List.reverse argSnocList)) argConsList 246 | in foldr fnStep (foldr fnStep [] (List.reverse fnSnocList)) fnConsList 247 | in Deque consList [] 248 | 249 | instance Monad Deque where 250 | return = pure 251 | (>>=) (Deque aConsList aSnocList) k = 252 | let consList = 253 | let aStep a accBConsList = case k a of 254 | Deque bConsList bSnocList -> bConsList <> foldl' (flip (:)) accBConsList bSnocList 255 | in foldr aStep (foldr aStep [] (List.reverse aSnocList)) aConsList 256 | in Deque consList [] 257 | #if !(MIN_VERSION_base(4,13,0)) 258 | fail = const mempty 259 | #endif 260 | 261 | instance Alternative Deque where 262 | empty = mempty 263 | (<|>) = mappend 264 | 265 | instance MonadPlus Deque where 266 | mzero = empty 267 | mplus = (<|>) 268 | 269 | instance MonadFail Deque where 270 | fail = const mempty 271 | 272 | -- | 273 | -- \(\mathcal{O}(1)\). 274 | instance IsList (Deque a) where 275 | type Item (Deque a) = a 276 | fromList = flip Deque [] 277 | toList (Deque consList snocList) = consList <> List.reverse snocList 278 | 279 | deriving instance Generic (Deque a) 280 | 281 | deriving instance Generic1 Deque 282 | 283 | instance (Hashable a) => Hashable (Deque a) 284 | 285 | instance (NFData a) => NFData (Deque a) 286 | 287 | instance NFData1 Deque 288 | -------------------------------------------------------------------------------- /library/Deque/Strict/Defs.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | -- | 4 | -- Definitions of strict Deque. 5 | -- 6 | -- The typical `toList` and `fromList` conversions are provided by means of 7 | -- the `Foldable` and `IsList` instances. 8 | module Deque.Strict.Defs where 9 | 10 | import Deque.Prelude hiding (dropWhile, filter, head, init, last, null, reverse, tail, take, takeWhile) 11 | import qualified Deque.Prelude as Prelude 12 | import qualified StrictList 13 | 14 | -- | 15 | -- Strict double-ended queue (aka Dequeue or Deque) based on head-tail linked list. 16 | data Deque a = Deque !(StrictList.List a) !(StrictList.List a) 17 | 18 | -- | 19 | -- \(\mathcal{O}(n)\). 20 | -- Construct from cons and snoc lists. 21 | {-# INLINE fromConsAndSnocLists #-} 22 | fromConsAndSnocLists :: [a] -> [a] -> Deque a 23 | fromConsAndSnocLists consList snocList = Deque (fromList consList) (fromList snocList) 24 | 25 | -- | 26 | -- \(\mathcal{O}(1)\). 27 | -- Add element in the beginning. 28 | {-# INLINE cons #-} 29 | cons :: a -> Deque a -> Deque a 30 | cons a (Deque consList snocList) = Deque (StrictList.Cons a consList) snocList 31 | 32 | -- | 33 | -- \(\mathcal{O}(1)\). 34 | -- Add element in the ending. 35 | {-# INLINE snoc #-} 36 | snoc :: a -> Deque a -> Deque a 37 | snoc a (Deque consList snocList) = Deque consList (StrictList.Cons a snocList) 38 | 39 | -- | 40 | -- \(\mathcal{O}(1)\). 41 | -- Reverse the deque. 42 | {-# INLINE reverse #-} 43 | reverse :: Deque a -> Deque a 44 | reverse (Deque consList snocList) = Deque snocList consList 45 | 46 | -- | 47 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 48 | -- Move the first element to the end. 49 | -- 50 | -- @ 51 | -- λ toList . shiftLeft $ fromList [1,2,3] 52 | -- [2,3,1] 53 | -- @ 54 | {-# INLINE shiftLeft #-} 55 | shiftLeft :: Deque a -> Deque a 56 | shiftLeft deque = maybe deque (uncurry snoc) (uncons deque) 57 | 58 | -- | 59 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 60 | -- Move the last element to the beginning. 61 | -- 62 | -- @ 63 | -- λ toList . shiftRight $ fromList [1,2,3] 64 | -- [3,1,2] 65 | -- @ 66 | {-# INLINE shiftRight #-} 67 | shiftRight :: Deque a -> Deque a 68 | shiftRight deque = maybe deque (uncurry cons) (unsnoc deque) 69 | 70 | balanceLeft :: Deque a -> Deque a 71 | balanceLeft = error "TODO" 72 | 73 | -- | 74 | -- \(\mathcal{O}(n)\). 75 | -- Leave only the elements satisfying the predicate. 76 | {-# INLINE filter #-} 77 | filter :: (a -> Bool) -> Deque a -> Deque a 78 | filter predicate (Deque consList snocList) = 79 | let newConsList = 80 | StrictList.prependReversed 81 | (StrictList.filterReversed predicate consList) 82 | (StrictList.filterReversed predicate snocList) 83 | in Deque newConsList StrictList.Nil 84 | 85 | -- | 86 | -- \(\mathcal{O}(n)\). 87 | -- Leave only the specified amount of first elements. 88 | take :: Int -> Deque a -> Deque a 89 | take amount (Deque consList snocList) = 90 | let newSnocList = 91 | let buildFromConsList amount !list = 92 | if amount > 0 93 | then \case 94 | StrictList.Cons head tail -> buildFromConsList (pred amount) (StrictList.Cons head list) tail 95 | _ -> buildFromSnocList amount list (StrictList.reverse snocList) 96 | else const list 97 | buildFromSnocList amount !list = 98 | if amount > 0 99 | then \case 100 | StrictList.Cons head tail -> buildFromSnocList (pred amount) (StrictList.Cons head list) tail 101 | _ -> list 102 | else const list 103 | in buildFromConsList amount StrictList.Nil consList 104 | in Deque StrictList.Nil newSnocList 105 | 106 | -- | 107 | -- \(\mathcal{O}(n)\). 108 | -- Drop the specified amount of first elements. 109 | drop :: Int -> Deque a -> Deque a 110 | drop amount (Deque consList snocList) = 111 | let buildFromConsList amount = 112 | if amount > 0 113 | then \case 114 | StrictList.Cons _ tail -> buildFromConsList (pred amount) tail 115 | _ -> buildFromSnocList amount (StrictList.reverse snocList) 116 | else \tail -> Deque tail snocList 117 | buildFromSnocList amount = 118 | if amount > 0 119 | then \case 120 | StrictList.Cons _ tail -> buildFromSnocList (pred amount) tail 121 | _ -> Deque StrictList.Nil StrictList.Nil 122 | else \tail -> Deque tail StrictList.Nil 123 | in buildFromConsList amount consList 124 | 125 | -- | 126 | -- \(\mathcal{O}(n)\). 127 | -- Leave only the first elements satisfying the predicate. 128 | {-# INLINE takeWhile #-} 129 | takeWhile :: (a -> Bool) -> Deque a -> Deque a 130 | takeWhile predicate (Deque consList snocList) = 131 | let newConsList = 132 | foldr 133 | ( \a nextState -> 134 | if predicate a 135 | then StrictList.Cons a nextState 136 | else StrictList.Nil 137 | ) 138 | (StrictList.takeWhileFromEnding predicate snocList) 139 | consList 140 | in Deque newConsList StrictList.Nil 141 | 142 | -- | 143 | -- \(\mathcal{O}(n)\). 144 | -- Drop the first elements satisfying the predicate. 145 | {-# INLINE dropWhile #-} 146 | dropWhile :: (a -> Bool) -> Deque a -> Deque a 147 | dropWhile predicate (Deque consList snocList) = 148 | let newConsList = StrictList.dropWhile predicate consList 149 | in case newConsList of 150 | StrictList.Nil -> Deque (StrictList.dropWhileFromEnding predicate snocList) StrictList.Nil 151 | _ -> Deque newConsList snocList 152 | 153 | -- | 154 | -- \(\mathcal{O}(n)\). 155 | -- Perform `takeWhile` and `dropWhile` in a single operation. 156 | span :: (a -> Bool) -> Deque a -> (Deque a, Deque a) 157 | span predicate (Deque consList snocList) = case StrictList.spanReversed predicate consList of 158 | (consReversedPrefix, consSuffix) -> 159 | if Prelude.null consSuffix 160 | then case StrictList.spanFromEnding predicate snocList of 161 | (snocPrefix, snocSuffix) -> 162 | let prefix = Deque (StrictList.prependReversed consReversedPrefix snocPrefix) StrictList.Nil 163 | suffix = Deque snocSuffix StrictList.Nil 164 | in (prefix, suffix) 165 | else 166 | let prefix = Deque StrictList.Nil consReversedPrefix 167 | suffix = Deque consSuffix snocList 168 | in (prefix, suffix) 169 | 170 | -- | 171 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 172 | -- Get the first element and deque without it if it's not empty. 173 | {-# INLINE uncons #-} 174 | uncons :: Deque a -> Maybe (a, Deque a) 175 | uncons (Deque consList snocList) = case consList of 176 | StrictList.Cons head tail -> Just (head, Deque tail snocList) 177 | _ -> case StrictList.reverse snocList of 178 | StrictList.Cons head tail -> Just (head, Deque tail StrictList.Nil) 179 | _ -> Nothing 180 | 181 | -- | 182 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 183 | -- Get the last element and deque without it if it's not empty. 184 | {-# INLINE unsnoc #-} 185 | unsnoc :: Deque a -> Maybe (a, Deque a) 186 | unsnoc (Deque consList snocList) = case snocList of 187 | StrictList.Cons head tail -> Just (head, Deque consList tail) 188 | _ -> case StrictList.reverse consList of 189 | StrictList.Cons head tail -> Just (head, Deque StrictList.Nil tail) 190 | _ -> Nothing 191 | 192 | -- | 193 | -- \(\mathcal{O}(1)\). 194 | -- Check whether deque is empty. 195 | {-# INLINE null #-} 196 | null :: Deque a -> Bool 197 | null = \case 198 | Deque StrictList.Nil StrictList.Nil -> True 199 | _ -> False 200 | 201 | -- | 202 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 203 | -- Get the first element if deque is not empty. 204 | {-# INLINE head #-} 205 | head :: Deque a -> Maybe a 206 | head (Deque consList snocList) = case consList of 207 | StrictList.Cons head _ -> Just head 208 | _ -> StrictList.last snocList 209 | 210 | -- | 211 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 212 | -- Get the last element if deque is not empty. 213 | {-# INLINE last #-} 214 | last :: Deque a -> Maybe a 215 | last (Deque consList snocList) = case snocList of 216 | StrictList.Cons head _ -> Just head 217 | _ -> StrictList.last consList 218 | 219 | -- | 220 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 221 | -- Keep all elements but the first one. 222 | -- 223 | -- In case of empty deque returns an empty deque. 224 | {-# INLINE tail #-} 225 | tail :: Deque a -> Deque a 226 | tail (Deque consList snocList) = case consList of 227 | StrictList.Cons _ consListTail -> Deque consListTail snocList 228 | _ -> Deque (StrictList.initReversed snocList) StrictList.Nil 229 | 230 | -- | 231 | -- \(\mathcal{O}(1)\), occasionally \(\mathcal{O}(n)\). 232 | -- Keep all elements but the last one. 233 | -- 234 | -- In case of empty deque returns an empty deque. 235 | {-# INLINE init #-} 236 | init :: Deque a -> Deque a 237 | init (Deque consList snocList) = case snocList of 238 | StrictList.Nil -> Deque StrictList.Nil (StrictList.initReversed consList) 239 | _ -> Deque consList (StrictList.tail snocList) 240 | 241 | instance (Eq a) => Eq (Deque a) where 242 | (==) a b = toList a == toList b 243 | 244 | instance (Show a) => Show (Deque a) where 245 | show = show . toList 246 | 247 | instance IsList (Deque a) where 248 | type Item (Deque a) = a 249 | fromList list = Deque StrictList.Nil (StrictList.fromListReversed list) 250 | toList (Deque consList snocList) = foldr (:) (toList (StrictList.reverse snocList)) consList 251 | 252 | instance Semigroup (Deque a) where 253 | (<>) (Deque consList1 snocList1) (Deque consList2 snocList2) = 254 | let consList = consList1 255 | snocList = snocList2 <> StrictList.prependReversed consList2 snocList1 256 | in Deque consList snocList 257 | 258 | instance Monoid (Deque a) where 259 | mempty = Deque StrictList.Nil StrictList.Nil 260 | mappend = (<>) 261 | 262 | deriving instance Functor Deque 263 | 264 | instance Foldable Deque where 265 | foldr step init (Deque consList snocList) = foldr step (foldr step init (StrictList.reverse snocList)) consList 266 | foldl' step init (Deque consList snocList) = foldl' step (foldl' step init consList) (StrictList.reverse snocList) 267 | 268 | instance Traversable Deque where 269 | traverse f (Deque cs ss) = 270 | (\cs' ss' -> Deque cs' (StrictList.reverse ss')) <$> traverse f cs <*> traverse f (StrictList.reverse ss) 271 | 272 | instance Applicative Deque where 273 | pure a = Deque (pure a) StrictList.Nil 274 | (<*>) (Deque fnConsList fnSnocList) (Deque argConsList argSnocList) = 275 | let snocList = 276 | let fnStep resultSnocList fn = 277 | let argStep resultSnocList arg = StrictList.Cons (fn arg) resultSnocList 278 | in foldl' argStep (foldl' argStep resultSnocList argConsList) (StrictList.reverse argSnocList) 279 | in foldl' fnStep (foldl' fnStep StrictList.Nil fnConsList) (StrictList.reverse fnSnocList) 280 | in Deque StrictList.Nil snocList 281 | 282 | instance Monad Deque where 283 | return = pure 284 | (>>=) (Deque aConsList aSnocList) k = 285 | let snocList = 286 | let aStep accBSnocList a = case k a of 287 | Deque bConsList bSnocList -> StrictList.prependReversed bConsList (bSnocList <> accBSnocList) 288 | in foldl' aStep (foldl' aStep StrictList.Nil aConsList) (StrictList.reverse aSnocList) 289 | in Deque StrictList.Nil snocList 290 | #if !(MIN_VERSION_base(4,13,0)) 291 | fail = const mempty 292 | #endif 293 | 294 | instance Alternative Deque where 295 | empty = mempty 296 | (<|>) = mappend 297 | 298 | instance MonadPlus Deque where 299 | mzero = empty 300 | mplus = (<|>) 301 | 302 | instance MonadFail Deque where 303 | fail = const mempty 304 | 305 | deriving instance Generic (Deque a) 306 | 307 | deriving instance Generic1 Deque 308 | 309 | instance (Hashable a) => Hashable (Deque a) 310 | 311 | instance (NFData a) => NFData (Deque a) 312 | 313 | instance NFData1 Deque 314 | --------------------------------------------------------------------------------