úÎ<Ï:01      !"#$%&'()*+,-./0<For a bounded deque, pushing may fail if the deque is full. 7Create a new, bounded deque with a specified capacity. <For a bounded deque, pushing may fail if the deque is full. FPushing is not the native operation for the right end, so it requires  that end be a . BPopL is not the native operation for the left end, so it requires  that the left end be a #, but places no other requirements  on the input queue. @Class encompassing the basic queue operations that hold for all A single, 1.5, and double ended modes. We arbitrarily call the  ends "left" and "right") and choose the natural operations to be 1 pushing on the left and popping on the right. <Create a new deque. Most appropriate for unbounded deques. ( If bounded, the size is unspecified. QIs the queue currently empty? Beware that this can be a highly transient state. 3Natural push: push onto the left end of the deque. 2Natural pop: pop from the right end of the deque. ?Work-stealing deques (1.5 ended). Typically the worker pushes C and pops its own queue (left) whereas thieves only pop (right). A concurrent deque. A concurrent queue. 3A traditional single-threaded, single-ended queue. QPop operations may possibly duplicate elements. Hopefully with low probability! 'The queue will not duplicate elements. *The queue can grow as elements are added.  The queue has bounded capacity. 2This end of the queue supports both push and pop. <This end of the queue provides push-only (left) or pop-only ! (right) functionality. Thus a  /  combination ( is what is commonly referred to as a single ended queue , whereas   /  is  a double ended queue+. Heterogenous combinations are sometimes  colloquially referred to as "1.5 ended queues". <Only one thread at a time may access this end of the queue. Haskell IO threads (Control.Concurrent) may concurrently access ; this end of the queue. Note that this attribute is set + separately for the left and right ends. EA family of Deques implementations. A concrete Deque implementation B is selected based on the (phantom) type parameters, which encode  several choices. EFor example, a work stealing deque is threadsafe only on one end and  supports push/-pop on one end (and popo-only) on the other:  > (Deque NT T D S Grow elt) BNote, however, that the above example is overconstraining in many F situations. It demands an implementation which is NOT threadsafe on B one end and does NOT support push on one end, whereas both these & features would not hurt, if present. FThus when accepting a queue as input to a function you probably never > want to overconstrain by demanding a less-featureful option. For example, rather than (Deque NT D T S Grow elt)  You would probably want: (Deque nt D T s Grow elt)     7Stores a size bound (if any) as well as a mutable Seq. %  !"#$%&'()  !%"#'$&() %*8This test serially fills up a queue and then drains it. +This one splits the 1 threads into producers and C consumers. Each thread performs its designated operation as fast  as possible. The 2 argument total designates how many total / items should be communicated (irrespective of 1). ,@This creates an HUnit test list to perform all the tests above. -Trivial test: push then pop. .-Trivial test: push left, pop left and right. /*Aggregate tests for work stealing queues. 0*+,-./0*+,-./0*+,-./03      !"#$%   &'()*+,-./0123abstract-deque-0.1.4Data.Concurrent.Deque.ClassData.Concurrent.Deque.ReferenceData.Concurrent.Deque.Tests-Data.Concurrent.Deque.Reference.DequeInstanceBoundedRtryPushRBoundedL newBoundedQtryPushLPushRpushRPopLtryPopL DequeClassnewQnullQpushLtryPopRWSDeque ConcDeque ConcQueueQueueDSNTTDupSafeGrowBound DoubleEnd SingleEnd Nonthreadsafe ThreadsafeDeque SimpleDequeDQtest_fifo_filldraintest_fifo_HalfToHalf test_fifo test_ws_triv1 test_ws_triv2 test_wsqueuetest_allbase GHC.Conc.SyncnumCapabilitiesghc-prim GHC.TypesInt