module Control.Monad.Queue.Allison
( Q()
, LenType
, enQ
, peekQ
, peekQn
, peekQs
, deQ
, deQs
, deQ_break
, lenQ
, lenQ_
, runQueue
, callCC
) where
import qualified Control.Monad.Queue.Class as Class
import Control.Monad.Queue.Util
import Data.List(genericIndex, genericTake, genericSplitAt)
type QSt e = LenType -> [e] -> [e]
newtype Q e a = Q { unQ :: (a -> QSt e) -> QSt e }
instance Monad (Q e) where
return a = Q (\k -> k a)
m >>= f = Q (\k -> unQ m (\a -> unQ (f a) k))
callCC :: ((a -> forall b. Q e b) -> Q e a) -> Q e a
callCC f = Q (\k -> unQ (f (\a -> Q (\_ -> k a))) k)
enQ :: e -> Q e ()
enQ e = Q (\k n q -> e : (k () $! n+1) q)
deQ :: Q e (Maybe e)
deQ = Q delta
where
delta k n q
| n <= 0 = k Nothing n q
| otherwise = case q of
[] -> error "Control.Monad.Queue.Allison.deQ: empty list"
(e:q') -> (k (Just e) $! n1) q'
deQ_break :: Q e e
deQ_break = Q delta
where
delta k n q
| n <= 0 = []
| otherwise = case q of
[] -> error "Control.Monad.Queue.Allison.deQ_break: empty list"
(e:q') -> (k e $! n1) q'
deQs :: Integral len => len -> Q e [e]
deQs i = Q delta
where
delta k n q
= let i' = min (fromIntegral i) n
(res,q') = genericSplitAt i' q
in (k res $! ni') q'
peekQ :: Q e (Maybe e)
peekQ = Q delta
where
delta k n q
| n <= 0 = k Nothing n q
| otherwise = case q of
[] -> error "Control.Monad.Queue.Allison.peekQ: empty list"
(e:_q') -> k (Just e) n q
peekQn :: (Integral index) => index -> Q e (Maybe e)
peekQn i_ = Q delta
where
i = fromIntegral i_
delta k n q
| n < i = k Nothing n q
| otherwise = k (Just (genericIndex q i)) n q
peekQs :: (Integral len) => len -> Q e [e]
peekQs i_ = Q delta
where
i = fromIntegral i_
delta k n q = k (genericTake (min i n) q) n q
lenQ_ :: Q e LenType
lenQ_ = Q (\k n q -> k n n q)
lenQ :: Integral len => Q e len
lenQ = Q (\k n q -> k (fromIntegral n) n q)
runQueue :: Q e a -> [e]
runQueue m = q
where
q = unQ m (\_ _ _ -> []) 0 q
instance Class.MonadQueue e (Q e) where
enQ = enQ
peekQ = peekQ
peekQs = peekQs
peekQn = peekQn
deQ = deQ
deQs = deQs
lenQ = lenQ