diff --git a/Data/PQueue/Internals.hs b/Data/PQueue/Internals.hs
--- a/Data/PQueue/Internals.hs
+++ b/Data/PQueue/Internals.hs
@@ -39,13 +39,7 @@
 
 import Prelude hiding (foldl, foldr, null)
 
--- | A priority queue implementation.  Implemented as a find-min wrapper around a binomial heap.
--- 
--- If you wish to perform folds on a priority queue that respect order, use 'foldrAsc' or
--- 'foldlAsc'.
--- 
--- For any operation @op@ in 'Eq' or 'Ord', @queue1 `op` queue2@ is equivalent to
--- @toAscList queue1 `op` toAscList queue2@.
+-- | A priority queue with elements of type @a@.  Supports extracting the minimum element.
 data MinQueue a = Empty | MinQueue {-# UNPACK #-} !Int a !(BinomHeap a)
 
 #ifdef __GLASGOW_HASKELL__
@@ -168,10 +162,13 @@
 size Empty = 0
 size (MinQueue n _ _) = n
 
+-- | Returns the minimum element of the queue, if the queue is nonempty.
 getMin :: MinQueue a -> Maybe a
 getMin (MinQueue _ x _) = Just x
 getMin _ = Nothing
 
+-- | Retrieves the minimum element of the queue, and the queue stripped of that element, 
+-- or 'Nothing' if passed an empty queue.
 minView :: Ord a => MinQueue a -> Maybe (a, MinQueue a)
 minView Empty = Nothing
 minView (MinQueue n x ts) = Just (x, case extractHeap ts of
@@ -427,6 +424,7 @@
 foldrU _ z Empty = z
 foldrU f z (MinQueue _ x ts) = x `f` foldr f z ts
 
+-- | /O(n)/.  Unordered left fold on a priority queue.
 foldlU :: (b -> a -> b) -> b -> MinQueue a -> b
 foldlU _ z Empty = z
 foldlU f z (MinQueue _ x ts) = foldl f (z `f` x) ts
diff --git a/Data/PQueue/Max.hs b/Data/PQueue/Max.hs
--- a/Data/PQueue/Max.hs
+++ b/Data/PQueue/Max.hs
@@ -1,33 +1,50 @@
 {-# LANGUAGE CPP #-}
 
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.PQueue.Min
+-- Copyright   :  (c) Louis Wasserman 2010
+-- License     :  BSD-style
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- General purpose priority queue, supporting maxView-maximum operations.
+--
+-- An amortized running time is given for each operation, with /n/ referring
+-- to the length of the sequence and /i/ being the integral index used by
+-- some operations.  These bounds hold even in a persistent (shared) setting.
+--
+-- This implementation is based on a binomial heap augmented with a global root.
+-- The spine of the heap is maintained lazily.  To force the spine of the heap,
+-- use 'seqSpine'.
+--
+-- This implementation does not guarantee stable behavior.
+-- 
+-- This implementation offers a number of methods of the form @xxxU@, where @U@ stands for
+-- unordered.  No guarantees whatsoever are made on the execution or traversal order of
+-- these functions.
+-----------------------------------------------------------------------------
 module Data.PQueue.Max (
 	MaxQueue,
-	-- * Construction
+	-- * Basic operations
 	empty,
-	singleton,
-	insert,
-	union,
-	unions,
-	-- * Query
 	null,
-	size,
-	-- ** Maximum view
+	size, 
+	-- * Query operations
 	findMax,
 	getMax,
 	deleteMax,
 	deleteFindMax,
 	maxView,
-	-- * Traversal
-	-- ** Map
-	map,
-	mapMonotonic,
-	-- ** Fold
-	foldr,
-	foldl,
-	-- ** Traverse
-	traverse,
+	-- * Construction operations
+	singleton,
+	insert,
+	union,
+	unions,
 	-- * Subsets
-	-- ** Indexed
+	-- ** Extracting subsets
+	(!!),
 	take,
 	drop,
 	splitAt,
@@ -36,35 +53,49 @@
 	dropWhile,
 	span,
 	break,
-	-- *** Filter
+	-- * Filter/Map
 	filter,
 	partition,
+	mapMaybe,
+	mapEither,
+	-- * Fold\/Functor\/Traversable variations
+	map,
+	foldrAsc,
+	foldlAsc,
+	foldrDesc,
+	foldlDesc,
 	-- * List operations
-	-- ** Conversion from lists
-	fromList,
-	fromDescList,
-	fromAscList,
-	-- ** Conversion to lists
-	elems,
 	toList,
+	toAscList,
 	toDescList,
-	-- * Conversion with MaxPQueue
-	pqueueKeys,
+	fromList,
+	fromAscList,
+	fromDescList,
 	-- * Unordered operations
+	mapU,
 	foldrU,
 	foldlU,
+	traverseU,
+	elemsU,
 	toListU,
-	-- * Helper methods
+	-- * Miscellaneous operations
+	keysQueue,
 	seqSpine) where
 
-import Control.Applicative hiding (empty)
-import Data.Maybe hiding (mapMaybe)
+import Control.Applicative (Applicative(..), (<$>))
+
 import Data.Monoid
-import qualified Data.List as List
-import qualified Data.PQueue.Prio.Max as Q
+import Data.Maybe hiding (mapMaybe)
+import Data.Foldable hiding (toList)
+import Data.Traversable
+import Data.Ord
 
-import Prelude hiding (map, filter, break, span, takeWhile, dropWhile, splitAt, take, drop, (!!), null, foldr, foldl)
+import qualified Data.PQueue.Min as Min
+import qualified Data.PQueue.Prio.Max.Internals as Prio
+import Data.PQueue.Prio.Max.Internals (Down(..))
 
+import Prelude hiding (null, foldr, foldl, take, drop, takeWhile, dropWhile, splitAt, span, break, (!!), filter)
+
 #ifdef __GLASGOW_HASKELL__
 import GHC.Exts (build)
 import Text.Read (Lexeme(Ident), lexP, parens, prec,
@@ -75,143 +106,241 @@
 build f = f (:) []
 #endif
 
-newtype MaxQueue a = MaxQ (Q.MaxPQueue a ()) deriving (Eq, Ord)
-
-null :: MaxQueue a -> Bool
-null (MaxQ q) = Q.null q
+-- | A priority queue implementation.  Implemented as a wrapper around "Data.PQueue.Min". 
+-- /Warning/: the 'Functor', 'Foldable', and 'Traversable' instances of this type /ignore ordering/.
+-- For 'Functor', it is guaranteed that if @f@ is a monotonic function, then @'fmap' f@ on a valid
+-- 'MaxQueue' will return a valid 'MaxQueue'.  An analogous guarantee holds for 'traverse'.  (Note:
+-- if passed constant-time operations, every function in 'Functor', 'Foldable', and 'Traversable'
+-- will run in /O(n)/.)
+-- 
+-- If you wish to perform folds on a priority queue that respect order, use 'foldrDesc' or
+-- 'foldlDesc'.
+newtype MaxQueue a = MaxQ (Min.MinQueue (Down a))
+# if __GLASGOW_HASKELL__
+	deriving (Eq, Ord, Data, Typeable)
+# else
+	deriving (Eq, Ord)
+# endif
 
-size :: MaxQueue a -> Int
-size (MaxQ q) = Q.size q
+instance (Ord a, Show a) => Show (MaxQueue a) where
+	showsPrec p xs = showParen (p > 10) $
+		showString "fromDescList " . shows (toDescList xs)
+		
+instance Read a => Read (MaxQueue a) where
+#ifdef __GLASGOW_HASKELL__
+	readPrec = parens $ prec 10 $ do
+		Ident "fromDescList" <- lexP
+		xs <- readPrec
+		return (fromDescList xs)
 
-empty :: MaxQueue a
-empty = MaxQ Q.empty
+	readListPrec = readListPrecDefault
+#else
+	readsPrec p = readParen (p > 10) $ \ r -> do
+		("fromDescList",s) <- lex r
+		(xs,t) <- reads s
+		return (fromDescList xs,t)
+#endif
 
-singleton :: a -> MaxQueue a
-singleton a = MaxQ (Q.singleton a ())
+instance Ord a => Monoid (MaxQueue a) where
+	mempty = empty
+	mappend = union
 
-insert :: Ord a => a -> MaxQueue a -> MaxQueue a
-insert a (MaxQ q) = MaxQ (Q.insert a () q)
+-- | /O(1)/.  The empty priority queue.
+empty :: MaxQueue a
+empty = MaxQ Min.empty
 
-union :: Ord a => MaxQueue a -> MaxQueue a -> MaxQueue a
-MaxQ q1 `union` MaxQ q2 = MaxQ (q1 `Q.union` q2)
+-- | /O(1)/.  Is this the empty priority queue?
+null :: MaxQueue a -> Bool
+null (MaxQ q) = Min.null q
 
-unions :: Ord a => [MaxQueue a] -> MaxQueue a
-unions qs = MaxQ (Q.unions [q | MaxQ q <- qs])
+-- | /O(1)/.  The number of elements in the queue.
+size :: MaxQueue a -> Int
+size (MaxQ q) = Min.size q
 
+-- | /O(1)/.  Returns the maximum element of the queue.  Throws an error on an empty queue.
 findMax :: MaxQueue a -> a
-findMax = fromMaybe (error "Error: findMax called on an empty queue") . getMax
+findMax = fromMaybe (error "Error: findMax called on empty queue") . getMax
 
+-- | /O(1)/.  The top (maximum) element of the queue, if there is one.
 getMax :: MaxQueue a -> Maybe a
-getMax (MaxQ q) = fst <$> Q.getMax q
+getMax (MaxQ q) = unDown <$> Min.getMin q
 
+-- | /O(log n)/.  Deletes the maximum element of the queue.  Does nothing on an empty queue.
 deleteMax :: Ord a => MaxQueue a -> MaxQueue a
-deleteMax (MaxQ q) = MaxQ (Q.deleteMax q)
+deleteMax (MaxQ q) = MaxQ (Min.deleteMin q)
 
+-- | /O(log n)/.  Extracts the maximum element of the queue.  Throws an error on an empty queue.
 deleteFindMax :: Ord a => MaxQueue a -> (a, MaxQueue a)
-deleteFindMax = fromMaybe (error "Error: deleteFindMax called on an empty queue") . maxView
+deleteFindMax = fromMaybe (error "Error: deleteFindMax called on empty queue") . maxView
 
+-- | /O(log n)/.  Extract the top (maximum) element of the sequence, if there is one.
 maxView :: Ord a => MaxQueue a -> Maybe (a, MaxQueue a)
-maxView (MaxQ q) = do
-	((a, _), q') <- Q.maxViewWithKey q
-	return (a, MaxQ q')
-
-map :: Ord b => (a -> b) -> MaxQueue a -> MaxQueue b
-map f (MaxQ q) = MaxQ (Q.mapKeys f q)
-
-mapMonotonic :: (a -> b) -> MaxQueue a -> MaxQueue b
-mapMonotonic f (MaxQ q) = MaxQ (Q.mapKeysMonotonic f q)
+maxView (MaxQ q) = case Min.minView q of
+	Nothing	-> Nothing
+	Just (Down x, q')
+		-> Just (x, MaxQ q')
+		
+-- | /O(log n)/.  Delete the top (maximum) element of the sequence, if there is one.
+delete :: Ord a => MaxQueue a -> Maybe (MaxQueue a)
+delete = fmap snd . maxView
 
-traverse :: (Applicative f, Ord a, Ord b) => (a -> f b) -> MaxQueue a -> f (MaxQueue b)
-traverse f q = case maxView q of
-	Nothing		-> pure empty
-	Just (a, q')	-> insert <$> f a <*> traverse f q'
+-- | /O(1)/.  Construct a priority queue with a single element.
+singleton :: a -> MaxQueue a
+singleton = MaxQ . Min.singleton . Down
 
-foldr :: Ord a => (a -> b -> b) -> b -> MaxQueue a -> b
-foldr f z (MaxQ q) = Q.foldrWithKey (const . f) z q
+-- | /O(1)/.  Insert an element into the priority queue.  
+insert :: Ord a => a -> MaxQueue a -> MaxQueue a
+x `insert` MaxQ q = MaxQ (Down x `Min.insert` q)
 
-foldl :: Ord a => (b -> a -> b) -> b -> MaxQueue a -> b
-foldl f z (MaxQ q) = Q.foldlWithKey (\ z -> const . f z) z q
+-- | /O(log (min(n1,n2)))/.  Take the union of two priority queues.
+union :: Ord a => MaxQueue a -> MaxQueue a -> MaxQueue a
+MaxQ q1 `union` MaxQ q2 = MaxQ (q1 `Min.union` q2)
 
-foldrU :: (a -> b -> b) -> b -> MaxQueue a -> b
-foldrU f z (MaxQ q) = Q.foldrWithKeyU (const . f) z q
+-- | Takes the union of a list of priority queues.  Equivalent to @'foldl' 'union' 'empty'@.
+unions :: Ord a => [MaxQueue a] -> MaxQueue a
+unions qs = MaxQ (Min.unions [q | MaxQ q <- qs])
 
-foldlU :: (b -> a -> b) -> b -> MaxQueue a -> b
-foldlU f z (MaxQ q) = Q.foldlWithKeyU (\ z -> const . f z) z q
+-- | /O(k log n)/.  Returns the @(k+1)@th largest element of the queue.
+(!!) :: Ord a => MaxQueue a -> Int -> a
+MaxQ q !! n = unDown ((Min.!!) q n)
 
--- {-# INLINE take #-}
+{-# INLINE take #-}
+-- | /O(k log n)/.  Returns the list of the @k@ largest elements of the queue, in descending order, or
+-- all elements of the queue, if @k >= n@.
 take :: Ord a => Int -> MaxQueue a -> [a]
-take k (MaxQ q) = List.map fst (Q.take k q)
+take k (MaxQ q) = [a | Down a <- Min.take k q]
 
+-- | /O(k log n)/.  Returns the queue with the @k@ largest elements deleted, or the empty queue if @k >= n@.
 drop :: Ord a => Int -> MaxQueue a -> MaxQueue a
-drop k (MaxQ q) = MaxQ (Q.drop k q)
+drop k (MaxQ q) = MaxQ (Min.drop k q)
 
+-- | /O(k log n)/.  Equivalent to @(take k queue, drop k queue)@.
 splitAt :: Ord a => Int -> MaxQueue a -> ([a], MaxQueue a)
-splitAt k (MaxQ q) = case Q.splitAt k q of
-	(xs, q') -> (List.map fst xs, MaxQ q')
-
+splitAt k (MaxQ q) = (map unDown xs, MaxQ q') where
+	(xs, q') = Min.splitAt k q
+	
+-- | 'takeWhile', applied to a predicate @p@ and a queue @queue@, returns the
+-- longest prefix (possibly empty) of @queue@ of elements that satisfy @p@.
 takeWhile :: Ord a => (a -> Bool) -> MaxQueue a -> [a]
-takeWhile p (MaxQ q) = List.map fst (Q.takeWhileWithKey (const . p) q)
+takeWhile p (MaxQ q) = map unDown (Min.takeWhile (p . unDown) q)
 
+-- | 'dropWhile' @p queue@ returns the queue remaining after 'takeWhile' @p queue@.
 dropWhile :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
-dropWhile p (MaxQ q) = MaxQ (Q.dropWhileWithKey (const . p) q)
+dropWhile p (MaxQ q) = MaxQ (Min.dropWhile (p . unDown) q)
 
+-- | 'span', applied to a predicate @p@ and a queue @queue@, returns a tuple where
+-- first element is longest prefix (possibly empty) of @queue@ of elements that
+-- satisfy @p@ and second element is the remainder of the queue.
+-- 
 span :: Ord a => (a -> Bool) -> MaxQueue a -> ([a], MaxQueue a)
-span p (MaxQ q) = case Q.spanWithKey (const . p) q of
-	(xs, q') -> (List.map fst xs, MaxQ q')
+span p (MaxQ q) = (map unDown xs, MaxQ q') where
+	(xs, q') = Min.span (p . unDown) q
 
+-- | 'break', applied to a predicate @p@ and a queue @queue@, returns a tuple where
+-- first element is longest prefix (possibly empty) of @queue@ of elements that
+-- /do not satisfy/ @p@ and second element is the remainder of the queue.
 break :: Ord a => (a -> Bool) -> MaxQueue a -> ([a], MaxQueue a)
-break p (MaxQ q) = case Q.breakWithKey (const . p) q of
-	(xs, q') -> (List.map fst xs, MaxQ q')
+break p = span (not . p)
 
+-- | /O(n)/.  Returns a queue of those elements which satisfy the predicate.
 filter :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
-filter f (MaxQ q) = MaxQ (Q.filterWithKey (const . f) q)
+filter p (MaxQ q) = MaxQ (Min.filter (p . unDown) q)
 
+-- | /O(n)/.  Returns a pair of queues, where the left queue contains those elements that satisfy the predicate,
+-- and the right queue contains those that do not.
 partition :: Ord a => (a -> Bool) -> MaxQueue a -> (MaxQueue a, MaxQueue a)
-partition p (MaxQ q) = case Q.partitionWithKey (const . p) q of
-	(q0, q1) -> (MaxQ q0, MaxQ q1)
+partition p (MaxQ q) = (MaxQ q0, MaxQ q1)
+	where	(q0, q1) = Min.partition (p . unDown) q
 
-{-# INLINE elems #-}
-elems :: Ord a => MaxQueue a -> [a]
-elems = toList
+-- | /O(n)/.  Maps a function over the elements of the queue, and collects the 'Just' values.
+mapMaybe :: Ord b => (a -> Maybe b) -> MaxQueue a -> MaxQueue b
+mapMaybe f (MaxQ q) = MaxQ (Min.mapMaybe (\ (Down x) -> Down <$> f x) q)
 
-{-# INLINE toList #-}
-toList :: Ord a => MaxQueue a -> [a]
-toList (MaxQ q) = Q.keys q
+-- | /O(n)/.  Maps a function over the elements of the queue, and separates the 'Left' and 'Right' values.
+mapEither :: (Ord b, Ord c) => (a -> Either b c) -> MaxQueue a -> (MaxQueue b, MaxQueue c)
+mapEither f (MaxQ q) = (MaxQ q0, MaxQ q1)
+	where	(q0, q1) = Min.mapEither (either (Left . Down) (Right . Down) . f . unDown) q
 
-{-# INLINE toDescList #-}
-toDescList :: Ord a => MaxQueue a -> [a]
-toDescList = toList
+-- | /O(n)/.  Assumes that the function it is given is monotonic, and applies this function to every element of the priority queue.
+-- /Does not check the precondition/.
+mapU :: (a -> b) -> MaxQueue a -> MaxQueue b
+mapU f (MaxQ q) = MaxQ (Min.mapU (\ (Down a) -> Down (f a)) q)
 
-{-# INLINE toAscList #-}
-toAscList :: Ord a => MaxQueue a -> [a]
-toAscList (MaxQ q) = List.map fst (Q.toAscList q)
+-- | /O(n)/.  Unordered right fold on a priority queue.
+foldrU :: (a -> b -> b) -> b -> MaxQueue a -> b
+foldrU f z (MaxQ q) = Min.foldrU (flip (foldr f)) z q
 
+-- | /O(n)/.  Unordered left fold on a priority queue.
+foldlU :: (b -> a -> b) -> b -> MaxQueue a -> b
+foldlU f z (MaxQ q) = Min.foldlU (foldl f) z q
+
 {-# INLINE elemsU #-}
-elemsU :: Ord a => MaxQueue a -> [a]
+-- | Equivalent to 'toListU'.
+elemsU :: MaxQueue a -> [a]
 elemsU = toListU
 
 {-# INLINE toListU #-}
-toListU :: Ord a => MaxQueue a -> [a]
-toListU (MaxQ q) = Q.keysU q
+-- | /O(n)/.  Returns a list of the elements of the priority queue, in no particular order.
+toListU :: MaxQueue a -> [a]
+toListU (MaxQ q) = map unDown (Min.toListU q)
 
-{-# INLINE fromList #-}
-fromList :: Ord a => [a] -> MaxQueue a
-fromList as = MaxQ (Q.fromList [(a, ()) | a <- as])
+-- | /O(n)/.  Assumes that the function it is given is monotonic, in some sense, and performs the 'traverse' operation.
+-- If the function is not monotonic, the result is undefined.
+traverseU :: (Applicative f, Ord b) => (a -> f b) -> MaxQueue a -> f (MaxQueue b)
+traverseU f (MaxQ q) = MaxQ <$> Min.traverseU (traverse f) q
 
-{-# INLINE fromDescList #-}
-fromDescList :: [a] -> MaxQueue a
-fromDescList as = MaxQ (Q.fromDescList [(a, ()) | a <- as])
+-- | /O(n log n)/.  Performs a right-fold on the elements of a priority queue in ascending order.
+-- @'foldrAsc' f z q == 'foldlDesc' (flip f) z q@.
+foldrAsc :: Ord a => (a -> b -> b) -> b -> MaxQueue a -> b
+foldrAsc = foldlDesc . flip
 
+-- | /O(n log n)/.  Performs a left-fold on the elements of a priority queue in descending order.
+-- @'foldlAsc' f z q == 'foldrDesc' (flip f) z q@.
+foldlAsc :: Ord a => (b -> a -> b) -> b -> MaxQueue a -> b
+foldlAsc = foldrDesc . flip
+
+-- | /O(n log n)/.  Performs a right-fold on the elements of a priority queue in descending order.
+foldrDesc :: Ord a => (a -> b -> b) -> b -> MaxQueue a -> b
+foldrDesc f z (MaxQ q) = Min.foldrAsc (flip (foldr f)) z q
+
+-- | /O(n log n)/.  Performs a left-fold on the elements of a priority queue in descending order.
+foldlDesc :: Ord a => (b -> a -> b) -> b -> MaxQueue a -> b
+foldlDesc f z (MaxQ q) = Min.foldlAsc (foldl f) z q
+
+{-# INLINE toAscList #-}
+-- | /O(n log n)/.  Extracts the elements of the priority queue in ascending order.
+toAscList :: Ord a => MaxQueue a -> [a]
+toAscList q = build (\ c nil -> foldrAsc c nil q)
+
+{-# INLINE toDescList #-}
+-- | /O(n log n)/.  Extracts the elements of the priority queue in descending order.
+toDescList :: Ord a => MaxQueue a -> [a]
+toDescList q = build (\ c nil -> foldrDesc c nil q)
+
+{-# INLINE toList #-}
+-- | /O(n)/.  Returns the elements of the priority queue in no particular order.
+toList :: Ord a => MaxQueue a -> [a]
+toList (MaxQ q) = map unDown (Min.toList q)
+
 {-# INLINE fromAscList #-}
+-- | /O(n)/.  Constructs a priority queue from an ascending list.  /Warning/: Does not check the precondition. 
 fromAscList :: [a] -> MaxQueue a
-fromAscList as = MaxQ (Q.fromAscList [(a, ()) | a <- as])
+fromAscList = MaxQ . Min.fromDescList . map Down
 
-pqueueKeys :: Q.MaxPQueue k a -> MaxQueue k
-#ifdef __GLASGOW_HASKELL__
-pqueueKeys q = MaxQ (() <$ q)
-#else
-pqueueKeys q = MaxQ (fmap (const ()) q)
-#endif
+{-# INLINE fromDescList #-}
+-- | /O(n)/.  Constructs a priority queue from a descending list.  /Warning/: Does not check the precondition.
+fromDescList :: [a] -> MaxQueue a
+fromDescList = MaxQ . Min.fromAscList . map Down
 
+{-# INLINE fromList #-}
+-- | /O(n log n)/.  Constructs a priority queue from an unordered list.
+fromList :: Ord a => [a] -> MaxQueue a
+fromList = foldr insert empty
+
+-- | /O(n)/.  Constructs a priority queue from the keys of a 'Prio.MaxPQueue'.
+keysQueue :: Prio.MaxPQueue k a -> MaxQueue k
+keysQueue (Prio.MaxPQ q) = MaxQ (Min.keysQueue q)
+
+-- | /O(log n)/.  Forces the spine of the heap.
 seqSpine :: MaxQueue a -> b -> b
-seqSpine (MaxQ q) = Q.seqSpine q
+seqSpine (MaxQ q) = Min.seqSpine q
diff --git a/Data/PQueue/Min.hs b/Data/PQueue/Min.hs
--- a/Data/PQueue/Min.hs
+++ b/Data/PQueue/Min.hs
@@ -16,13 +16,14 @@
 -- some operations.  These bounds hold even in a persistent (shared) setting.
 --
 -- This implementation is based on a binomial heap augmented with a global root.
--- The spine of the heap is maintained strictly, ensuring that computations happen
--- as they are performed.
+-- The spine of the heap is maintained lazily.  To force the spine of the heap,
+-- use 'seqSpine'.
 --
 -- This implementation does not guarantee stable behavior.
 -- 
--- /WARNING:/ 'toList' and 'toAscList' are /not/ equivalent, unlike for example
--- "Data.Map".
+-- This implementation offers a number of methods of the form @xxxU@, where @U@ stands for
+-- unordered.  No guarantees whatsoever are made on the execution or traversal order of
+-- these functions.
 -----------------------------------------------------------------------------
 module Data.PQueue.Min (
 	MinQueue,
@@ -59,11 +60,12 @@
 	mapEither,
 	-- * Fold\/Functor\/Traversable variations
 	map,
-	mapMonotonic,
 	foldrAsc,
 	foldlAsc,
 	foldrDesc,
 	foldlDesc,
+	traverseAsc,
+	traverseDesc,
 	-- * List operations
 	toList,
 	toAscList,
@@ -72,6 +74,7 @@
 	fromAscList,
 	fromDescList,
 	-- * Unordered operations
+	mapU,
 	foldrU,
 	foldlU,
 	traverseU,
@@ -130,14 +133,17 @@
 	mappend = union
 	mconcat = unions
 
+-- | /O(1)/.  Returns the minimum element.  Throws an error on an empty queue.
 findMin :: MinQueue a -> a
 findMin = fromMaybe (error "Error: findMin called on empty queue") . getMin
 
+-- | /O(log n)/.  Deletes the minimum element.  If the queue is empty, does nothing.
 deleteMin :: Ord a => MinQueue a -> MinQueue a
 deleteMin q = case minView q of
 	Nothing		-> empty
 	Just (_, q')	-> q'
 
+-- | /O(log n)/.  Extracts the minimum element.  Throws an error on an empty queue.
 deleteFindMin :: Ord a => MinQueue a -> (a, MinQueue a)
 deleteFindMin = fromMaybe (error "Error: deleteFindMin called on empty queue") . minView
 
@@ -258,6 +264,14 @@
 foldlDesc :: Ord a => (b -> a -> b) -> b -> MinQueue a -> b
 foldlDesc = foldrAsc . flip
 
+-- | /O(n log n)/.  Equivalent to @'fromList' <$> 'traverse' f ('toAscList' q)@.
+traverseAsc :: (Applicative f, Ord a, Ord b) => (a -> f b) -> MinQueue a -> f (MinQueue b)
+traverseAsc f = foldrAsc (\ a q -> insert <$> f a <*> q) (pure empty)
+
+-- | /O(n log n)/.  Equivalent to @'fromList' <$> 'traverse' f ('toDescList' q)@.
+traverseDesc :: (Applicative f, Ord a, Ord b) => (a -> f b) -> MinQueue a -> f (MinQueue b)
+traverseDesc f = foldrDesc (\ a q -> insert <$> f a <*> q) (pure empty)
+
 {-# INLINE fromList #-}
 -- | /O(n)/.  Constructs a priority queue from an unordered list.
 fromList :: Ord a => [a] -> MinQueue a
@@ -277,13 +291,22 @@
 fromDescList :: [a] -> MinQueue a
 fromDescList = foldl' (flip insertMinQ) empty
 
+-- | Maps a function over the elements of the queue, ignoring order.  This function is only safe if the function is monotonic.
+-- This function /does not/ check the precondition.
+mapU :: (a -> b) -> MinQueue a -> MinQueue b
+mapU = mapMonotonic
+
 {-# INLINE elemsU #-}
+-- | Equivalent to 'toListU'.
 elemsU :: MinQueue a -> [a]
 elemsU = toListU
 
+-- | Returns the elements of the queue, in no particular order.
 toListU :: MinQueue a -> [a]
 toListU q = build (\ c n -> foldrU c n q)
 
+-- | /O(n)/.  Iterates over the elements of the queue in no particular order, but returns a valid queue that
+-- respects the order of the returned elements.
 traverseU :: (Applicative f, Ord b) => (a -> f b) -> MinQueue a -> f (MinQueue b)
 traverseU f = foldrU (\ a q -> insert <$> f a <*> q) (pure empty)
 
diff --git a/Data/PQueue/Prio/Max.hs b/Data/PQueue/Prio/Max.hs
--- a/Data/PQueue/Prio/Max.hs
+++ b/Data/PQueue/Prio/Max.hs
@@ -9,24 +9,25 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- General purpose priority queue, supporting extract-minimum operations.
+-- General purpose priority queue.
 -- Each element is associated with a /key/, and the priority queue supports
--- viewing and extracting the element with the minimum key.
+-- viewing and extracting the element with the maximum key.
 --
--- An amortized running time is given for each operation, with /n/ referring
--- to the length of the sequence and /i/ being the integral index used by
--- some operations.  These bounds hold even in a persistent (shared) setting.
+-- A worst-case bound is given for each operation.  In some cases, an amortized
+-- bound is also specified; these bounds do not hold in a persistent context.
 --
 -- This implementation is based on a binomial heap augmented with a global root.
--- The spine of the heap is maintained lazily.
---
--- This implementation does not guarantee stable behavior.  Ties are broken
--- arbitrarily -- that is, if @k1 <= k2@ and @k2 <= k1@, then there are no
--- guarantees about the relative order in which @k1@, @k2@, and their associated
--- elements are returned.
+-- The spine of the heap is maintained lazily.  To force the spine of the heap,
+-- use 'seqSpine'.
 -- 
+-- We do not guarantee stable behavior.
+-- Ties are broken arbitrarily -- that is, if @k1 <= k2@ and @k2 <= k1@, then there 
+-- are no guarantees about the relative order in which @k1@, @k2@, and their associated
+-- elements are returned.  (Unlike Data.Map, we allow multiple elements with the
+-- same key.)
+-- 
 -- This implementation offers a number of methods of the form @xxxU@, where @U@ stands for
--- "unordered."  No guarantees are made on the execution or traversal order of
+-- unordered.  No guarantees whatsoever are made on the execution or traversal order of
 -- these functions.
 -----------------------------------------------------------------------------
 module Data.PQueue.Prio.Max (
@@ -120,6 +121,7 @@
 import Data.Foldable hiding (toList)
 import Data.Traversable
 import Data.Maybe hiding (mapMaybe)
+import Data.PQueue.Prio.Max.Internals
 
 import Prelude hiding (map, filter, break, span, takeWhile, dropWhile, splitAt, take, drop, (!!), null, foldr, foldl)
 
@@ -141,18 +143,24 @@
 second' :: (b -> c) -> (a, b) -> (a, c)
 second' f (a, b) = (a, f b)
 
-newtype Down a = Down {unDown :: a} deriving (Eq)
-
--- | A priority queue where values of type @a@ are annotated with keys of type @k@.
--- The queue supports extracting the element with maximum key.
-newtype MaxPQueue k a = MaxPQ (Q.MinPQueue (Down k) a) deriving (Eq, Ord)
+instance (Ord k, Show k, Show a) => Show (MaxPQueue k a) where
+	showsPrec p xs = showParen (p > 10) $
+		showString "fromDescList " . shows (toDescList xs)
 
-instance Ord a => Ord (Down a) where
-	Down a `compare` Down b = b `compare` a
-	Down a <= Down b = b <= a
+instance (Read k, Read a) => Read (MaxPQueue k a) where
+#ifdef __GLASGOW_HASKELL__
+	readPrec = parens $ prec 10 $ do
+		Ident "fromDescList" <- lexP
+		xs <- readPrec
+		return (fromDescList xs)
 
-instance Functor Down where
-	fmap f (Down a) = Down (f a)
+	readListPrec = readListPrecDefault
+#else
+	readsPrec p = readParen (p > 10) $ \ r -> do
+		("fromDescList",s) <- lex r
+		(xs,t) <- reads s
+		return (fromDescList xs,t)
+#endif
 
 instance Functor (MaxPQueue k) where
 	fmap f (MaxPQ q) = MaxPQ (fmap f q)
diff --git a/Data/PQueue/Prio/Max/Internals.hs b/Data/PQueue/Prio/Max/Internals.hs
new file mode 100644
--- /dev/null
+++ b/Data/PQueue/Prio/Max/Internals.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE CPP #-}
+
+module Data.PQueue.Prio.Max.Internals where
+
+import Control.Applicative
+
+import Data.Foldable
+import Data.Traversable
+# if __GLASGOW_HASKELL__
+import Data.Data
+# endif
+
+import Prelude hiding (foldr, foldl)
+
+import Data.PQueue.Prio.Internals (MinPQueue)
+
+newtype Down a = Down {unDown :: a} 
+# if __GLASGOW_HASKELL__
+	deriving (Eq, Data, Typeable)
+# else
+	deriving (Eq)
+# endif
+
+-- | A priority queue where values of type @a@ are annotated with keys of type @k@.
+-- The queue supports extracting the element with maximum key.
+newtype MaxPQueue k a = MaxPQ (MinPQueue (Down k) a) deriving (Eq, Ord)
+
+instance Ord a => Ord (Down a) where
+	Down a `compare` Down b = b `compare` a
+	Down a <= Down b = b <= a
+
+instance Functor Down where
+	fmap f (Down a) = Down (f a)
+
+
+instance Foldable Down where
+	foldr f z (Down a) = a `f` z
+	foldl f z (Down a) = z `f` a
+
+instance Traversable Down where
+	traverse f (Down a) = Down <$> f a
diff --git a/Data/PQueue/Prio/Min.hs b/Data/PQueue/Prio/Min.hs
--- a/Data/PQueue/Prio/Min.hs
+++ b/Data/PQueue/Prio/Min.hs
@@ -17,10 +17,13 @@
 -- bound is also specified; these bounds do not hold in a persistent context.
 --
 -- This implementation is based on a binomial heap augmented with a global root.
--- The spine of the heap is maintained lazily.  We do not guarantee stable behavior.
+-- The spine of the heap is maintained lazily.  To force the spine of the heap,
+-- use 'seqSpine'.
+-- 
+-- We do not guarantee stable behavior.
 -- Ties are broken arbitrarily -- that is, if @k1 <= k2@ and @k2 <= k1@, then there 
 -- are no guarantees about the relative order in which @k1@, @k2@, and their associated
--- elements are returned.  (Unlike "Data.Map", we allow multiple elements with the
+-- elements are returned.  (Unlike Data.Map, we allow multiple elements with the
 -- same key.)
 -- 
 -- This implementation offers a number of methods of the form @xxxU@, where @U@ stands for
diff --git a/pqueue.cabal b/pqueue.cabal
--- a/pqueue.cabal
+++ b/pqueue.cabal
@@ -1,5 +1,5 @@
 Name:		pqueue
-Version:	1.0.0
+Version:	1.0.1
 Category:	Data Structures
 Author:		Louis Wasserman
 License:	BSD3
@@ -26,6 +26,7 @@
   other-modules:
         Data.PQueue.Prio.Internals
         Data.PQueue.Internals
+        Data.PQueue.Prio.Max.Internals
 
   if impl(ghc) {
     extensions: DeriveDataTypeable
