{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, TypeFamilies, FlexibleContexts, UndecidableInstances #-} -- | Generic queue wrapper to transform a min-queue into a max-queue. module Data.Queue.ReverseQueue (Down(..), ReverseQueue) where import Data.Queue.Class newtype Down a = Down {unDown :: a} deriving (Eq) instance Ord a => Ord (Down a) where Down x `compare` Down y = case x `compare` y of LT -> GT EQ -> EQ GT -> LT Down x <= Down y = x >= y Down x >= Down y = x <= y Down x < Down y = x > y Down x > Down y = x < y -- | Wrapper around a generic queue that reverses the ordering on its elements. newtype ReverseQueue q e = RQ (q (Down e)) instance (Queuelike (q (Down e)), QueueKey (q (Down e)) ~ Down e) => Queuelike (ReverseQueue q e) where type QueueKey (ReverseQueue q e) = e singleton x = RQ (singleton (Down x)) empty = RQ empty fromList xs = RQ (fromList (map Down xs)) toList (RQ q) = map unDown (toList q) toList_ (RQ q) = map unDown (toList_ q) x `insert` RQ q = RQ (Down x `insert` q) extract (RQ q) = fmap (\ (Down x, q') -> (x, RQ q')) (extract q) peek (RQ q) = fmap unDown (peek q) delete (RQ q) = fmap RQ (delete q) insertAll xs (RQ q) = RQ (insertAll (map Down xs) q) isEmpty (RQ q) = isEmpty q RQ q1 `merge` RQ q2 = RQ (q1 `merge` q2)