-- | -- Module: Control.Wire.Prefab.Queue -- Copyright: (c) 2012 Ertugrul Soeylemez -- License: BSD3 -- Maintainer: Ertugrul Soeylemez -- -- Wires acting as queues. module Control.Wire.Prefab.Queue ( -- * Queues bag, fifo, lifo ) where import qualified Data.Set as S import qualified Data.Sequence as Seq import Control.Wire.Wire import Data.Monoid import Data.Set (Set) import Data.Sequence (ViewL(..), (><), viewl) -- | Incoming values are placed in a set, which is discharged element by -- element. Lower values are served first. Duplicate values are served -- once. -- -- Note: Incorrect usage can lead to congestion. -- -- * Complexity: O(n) space wrt bag size. -- -- * Depends: current instant. -- -- * Inhibits: when the bag is empty. bag :: (Monoid e, Ord b) => Wire e m (Set b) b bag = bag' S.empty where bag' s' = mkPure $ \_ xs -> case S.minView (S.union s' xs) of Nothing -> (Left mempty, bag' S.empty) Just (x, s) -> (Right x, bag' s) -- | First in, first out. The input list is placed on the right end of -- a queue at every instant, giving earlier elements a higher priority. -- The queue is discharged item by item from the left. -- -- Note: Incorrect usage can lead to congestion. -- -- * Complexity: O(n) space wrt queue size. -- -- * Depends: current instant. -- -- * Inhibits: when the queue is currently empty. fifo :: (Monoid e) => Wire e m [b] b fifo = fifo' Seq.empty where fifo' queue' = mkPure $ \_ xs -> case viewl (queue' >< Seq.fromList xs) of EmptyL -> (Left mempty, fifo' Seq.empty) x :< queue -> (Right x, fifo' queue) -- | Last in, first out. The input list is placed on a stack at every -- instant, giving earlier elements a higher priority. The stack is -- discharged item by item from the top. -- -- Note: Incorrect usage can lead to congestion. -- -- * Complexity: O(n) space wrt stack size. -- -- * Depends: current instant. -- -- * Inhibits: when the stack is currently empty. lifo :: (Monoid e) => Wire e m [b] b lifo = lifo' Seq.empty where lifo' queue' = mkPure $ \_ xs -> case viewl (Seq.fromList xs >< queue') of EmptyL -> (Left mempty, lifo' Seq.empty) x :< queue -> (Right x, lifo' queue)