77
88-- | Mutable Linear Deque
99--
10- -- This module provides a pure interface to a bounded mutable deque.
11- -- The deque has a maxiumum size and is represented with an array underneath.
10+ -- This module provides a pure interface to a mutable deque.
1211--
1312-- It is designed to be imported qualfied:
1413--
@@ -22,7 +21,6 @@ module Data.Deque.Mutable.Linear
2221 -- * Querying
2322 , size
2423 , length
25- , isFull
2624 , peekFront
2725 , peekBack
2826 -- * Modification
@@ -40,7 +38,6 @@ import qualified Data.Array.Mutable.Linear as Array
4038import Data.Unrestricted.Linear
4139import Prelude.Linear hiding (length , map )
4240import qualified Prelude
43- import GHC.Stack
4441
4542
4643-- # Types
@@ -90,14 +87,14 @@ nextPtr sz (Ptr p) = (p + 1) `mod` sz
9087-------------------------------------------------------------------------------
9188
9289-- | Run a computation of an empty Deque with a given size
93- alloc :: HasCallStack => Int -> (Deque a % 1 -> Ur b ) % 1 -> Ur b
90+ alloc :: Int -> (Deque a % 1 -> Ur b ) % 1 -> Ur b
9491alloc k f = Array. alloc k err $ \ arr -> f (Deque 0 0 arr) where
9592 err = Prelude. error " Accessing error element of a collection!"
9693
9794-- | Run a computation on a Deque that is deterimined by the given the list
9895-- where we treat the start and end of the list as the left and right pointers,
9996-- with the total capacity as the length of the list.
100- fromList :: HasCallStack => [a ] -> (Deque a % 1 -> Ur b ) % 1 -> Ur b
97+ fromList :: [a ] -> (Deque a % 1 -> Ur b ) % 1 -> Ur b
10198fromList xs f =
10299 Array. fromList xs $ \ arr -> f (Deque (Prelude. length xs) 0 arr)
103100
@@ -119,7 +116,7 @@ isFull :: Deque a %1-> (Ur Bool, Deque a)
119116isFull d =
120117 size d & \ (Ur sz, Deque len ptr arr) -> (Ur (len == sz), Deque len ptr arr)
121118
122- peek :: HasCallStack => Face -> Deque a % 1 -> (Ur (Maybe a ), Deque a )
119+ peek :: Face -> Deque a % 1 -> (Ur (Maybe a ), Deque a )
123120peek _ (Deque 0 p arr) = (Ur Nothing , Deque 0 p arr)
124121peek face (Deque len ptr@ (Ptr p) arr) = case face of
125122 Front ->
@@ -129,20 +126,20 @@ peek face (Deque len ptr@(Ptr p) arr) = case face of
129126 (Ur (Just a), Deque len ptr arr1)
130127
131128-- | View the top of the left queue
132- peekFront :: HasCallStack => Deque a % 1 -> (Ur (Maybe a ), Deque a )
129+ peekFront :: Deque a % 1 -> (Ur (Maybe a ), Deque a )
133130peekFront = peek Front
134131
135132-- | View the top of the right queue
136- peekBack :: HasCallStack => Deque a % 1 -> (Ur (Maybe a ), Deque a )
133+ peekBack :: Deque a % 1 -> (Ur (Maybe a ), Deque a )
137134peekBack = peek Back
138135
139136
140137-- # Modification
141138-------------------------------------------------------------------------------
142139
143- push :: HasCallStack => Face -> a -> Deque a % 1 -> Deque a
140+ push :: Face -> a -> Deque a % 1 -> Deque a
144141push face x deq = isFull deq & \ case
145- (Ur True , deq0) -> error " Pushing to full deque " $ deq0
142+ (Ur True , deq0) -> push face x (doubleSize deq0)
146143 (Ur False , Deque 0 _ arr) -> Array. write arr 0 x & \ arr0 -> Deque 1 0 arr0
147144 (Ur False , Deque len (Ptr p) arr) -> case face of
148145 Front -> Array. size arr & \ (Ur sz, arr0) ->
@@ -152,15 +149,28 @@ push face x deq = isFull deq & \case
152149 Array. write arr0 (backPtr 1 len sz (Ptr p)) x & \ arr1 ->
153150 Deque (len+ 1 ) (Ptr p) arr1
154151
152+ doubleSize :: Deque a % 1 -> Deque a
153+ doubleSize (Deque len ptr@ (Ptr start) arr) =
154+ Array. size arr & \ (Ur sz, arr0) ->
155+ Array. resize (sz* 2 ) err arr0 & \ arr1 ->
156+ Deque len ptr (movePrefix 0 start arr1)
157+ where
158+ err = Prelude. error " Accessing error element of a collection!"
159+ movePrefix :: Int -> Int -> Array. Array a % 1 -> Array. Array a
160+ movePrefix ix p arr'
161+ | ix == p = arr'
162+ | otherwise = Array. read arr' ix & \ (Ur a, arr0) ->
163+ Array. write arr0 (p+ ix+ 1 ) a & \ arr1 -> movePrefix (ix+ 1 ) p arr1
164+
155165-- | Push to the front end
156- pushFront :: HasCallStack => a -> Deque a % 1 -> Deque a
166+ pushFront :: a -> Deque a % 1 -> Deque a
157167pushFront = push Front
158168
159169-- | Push to the back end
160- pushBack :: HasCallStack => a -> Deque a % 1 -> Deque a
170+ pushBack :: a -> Deque a % 1 -> Deque a
161171pushBack = push Back
162172
163- pop :: HasCallStack => Face -> Deque a % 1 -> (Ur (Maybe a ), Deque a )
173+ pop :: Face -> Deque a % 1 -> (Ur (Maybe a ), Deque a )
164174pop _ (Deque 0 p arr) = (Ur Nothing , Deque 0 p arr)
165175pop face (Deque len ptr@ (Ptr p) arr) = case face of
166176 Front -> Array. size arr & \ (Ur sz, arr0) ->
@@ -181,6 +191,8 @@ popBack = pop Back
181191-- Note: We can't use a Prelude.Functor nor a Data.Functor
182192-- because the mapped function need not be linear but we must
183193-- consume the Deque linearly. The types don't align.
194+ -- Note: This could be more efficient if we only mapped the
195+ -- elements we care about and coerced the rest
184196map :: (a -> b ) -> Deque a % 1 -> Deque b
185197map f (Deque len p arr) = Deque len p (Array. map f arr)
186198
0 commit comments