diff --git a/monad-loops.cabal b/monad-loops.cabal
--- a/monad-loops.cabal
+++ b/monad-loops.cabal
@@ -1,20 +1,28 @@
 name:                   monad-loops
-version:                0.3.1.1
+version:                0.3.2.0
 stability:              provisional
 license:                BSD3
 license-file:           LICENSE
 
-cabal-version:          >= 1.2
+cabal-version:          >= 1.6
 build-type:             Simple
 
 author:                 James Cook <mokus@deepbondi.net>
 maintainer:             James Cook <mokus@deepbondi.net>
-homepage:               http://code.haskell.org/~mokus/monad-loops
+homepage:               https://github.com/mokus0/monad-loops
 
 category:               Control
 synopsis:               Monadic loops
-description:            Some useful control operators for looping
+description:            Some useful control operators for looping.
+                        .
+                        New in 0.3.2.0: various functions for traversing lists and 
+                        computing minima/maxima using arbitrary procedures to compare
+                        or score the elements.
 
+source-repository head
+  type: git
+  location: git://github.com/mokus0/monad-loops.git
+
 Flag useSTM
   Description:          Include instances for STM types
   Default:              True
@@ -30,7 +38,7 @@
     cpp-options:        -Dbase4
     build-depends:      base >= 4 && <5
   else
-    build-depends:      base < 4
+    build-depends:      base >= 2 && < 4
 
   if flag(useSTM)
     build-depends:      stm
diff --git a/src/Control/Monad/Loops.hs b/src/Control/Monad/Loops.hs
--- a/src/Control/Monad/Loops.hs
+++ b/src/Control/Monad/Loops.hs
@@ -39,6 +39,8 @@
 import Control.Monad.Loops.STM
 #endif
 
+import Data.Maybe (listToMaybe)
+
 -- possibly-useful addition? :
 -- concatMapM :: (Monad m, Traversable f, Monoid w) => (a -> m w) -> (f a) -> m w
 
@@ -289,13 +291,13 @@
 -- twist.  Rather than returning a list, it returns any MonadPlus type of your
 -- choice.
 unfoldrM' :: (Monad m, MonadPlus f) => (a -> m (Maybe (b,a))) -> a -> m (f b)
-unfoldrM' f z = go z
-    where go z = do
+unfoldrM' f z = go
+    where go = do
             x <- f z
             case x of
                 Nothing         -> return mzero
                 Just (x, z)     -> do
-                        xs <- go z
+                        xs <- go
                         return (return x `mplus` xs)
 
 {-# SPECIALIZE concatM :: [a -> IO a] -> (a -> IO a) #-}
@@ -396,3 +398,65 @@
         if q
                 then return (Just x)
                 else firstM p xs
+
+{-# INLINE minimaOnByM #-}
+minimaOnByM :: Monad m => (a -> m b) -> (b -> b -> m Ordering) -> [a] -> m [a]
+minimaOnByM _   _ []     = return []
+minimaOnByM f cmp (x:xs) = do
+    fx<- f x
+    loop (x:) fx xs
+        where   loop ms _ []           = return (ms [])
+                loop ms fm (x:xs) = do
+                    fx  <- f x
+                    ord <- cmp fm fx
+                    case ord of
+                        LT -> loop ms          fm xs
+                        EQ -> loop (ms . (x:)) fm xs
+                        GT -> loop (x:)        fx xs
+
+{-# INLINE maximaOnByM #-}
+maximaOnByM :: Monad m => (a -> m b) -> (b -> b -> m Ordering) -> [a] -> m [a]
+maximaOnByM f = minimaOnByM f . flip
+
+minimaByM :: Monad m => (a -> a -> m Ordering) -> [a] -> m [a]
+minimaByM = minimaOnByM return
+
+maximaByM :: Monad m => (a -> a -> m Ordering) -> [a] -> m [a]
+maximaByM = maximaOnByM return
+
+minimaOnM :: (Monad m, Ord b) => (a -> m b) -> [a] -> m [a]
+minimaOnM f = minimaOnByM f (\x y -> return (compare x y))
+
+maximaOnM :: (Monad m, Ord b) => (a -> m b) -> [a] -> m [a]
+maximaOnM f = maximaOnByM f (\x y -> return (compare x y))
+
+{-# INLINE minimumOnByM #-}
+minimumOnByM :: Monad m => (a -> m b) -> (b -> b -> m Ordering) -> [a] -> m (Maybe a)
+minimumOnByM _   _ []     = return Nothing
+minimumOnByM f cmp (x:xs) = do
+    fx <- f x
+    loop x fx xs
+        where   loop m _ []           = return (Just m)
+                loop m fm (x:xs) = do
+                    fx  <- f x
+                    ord <- cmp fm fx
+                    case ord of
+                        LT -> loop m fm xs
+                        EQ -> loop m fm xs
+                        GT -> loop x fx xs
+
+{-# INLINE maximumOnByM #-}
+maximumOnByM :: Monad m => (a -> m b) -> (b -> b -> m Ordering) -> [a] -> m (Maybe a)
+maximumOnByM f = minimumOnByM f . flip
+
+minimumByM :: Monad m => (a -> a -> m Ordering) -> [a] -> m (Maybe a)
+minimumByM = minimumOnByM return
+
+maximumByM :: Monad m => (a -> a -> m Ordering) -> [a] -> m (Maybe a)
+maximumByM = maximumOnByM return
+
+minimumOnM :: (Monad m, Ord b) => (a -> m b) -> [a] -> m (Maybe a)
+minimumOnM f = minimumOnByM f (\x y -> return (compare x y))
+
+maximumOnM :: (Monad m, Ord b) => (a -> m b) -> [a] -> m (Maybe a)
+maximumOnM f = maximumOnByM f (\x y -> return (compare x y))
