diff --git a/riak.cabal b/riak.cabal
--- a/riak.cabal
+++ b/riak.cabal
@@ -1,5 +1,5 @@
 name:                riak
-version:             0.4.1.1
+version:             0.5.0.0
 synopsis:            A Haskell client for the Riak decentralized data store
 description:
   A Haskell client library for the Riak decentralized data
diff --git a/src/Network/Riak/Basic.hs b/src/Network/Riak/Basic.hs
--- a/src/Network/Riak/Basic.hs
+++ b/src/Network/Riak/Basic.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
+{-# LANGUAGE BangPatterns, OverloadedStrings, RecordWildCards #-}
 
 -- |
 -- Module:      Network.Riak.Basic
@@ -50,7 +50,7 @@
 import Network.Riak.Protocol.BucketProps
 import Network.Riak.Protocol.Content
 import Network.Riak.Protocol.ListKeysResponse
-import Network.Riak.Protocol.MapReduce
+import Network.Riak.Protocol.MapReduce as MapReduce
 import Network.Riak.Protocol.ServerInfo
 import Network.Riak.Types.Internal hiding (MessageTag(..))
 import qualified Data.Foldable as F
@@ -137,6 +137,14 @@
 setBucket :: Connection -> T.Bucket -> BucketProps -> IO ()
 setBucket conn bucket props = exchange_ conn $ Req.setBucket bucket props
 
--- | Launch a 'MapReduce' job.
-mapReduce :: Connection -> Job -> IO MapReduce
-mapReduce conn = exchange conn . Req.mapReduce
+-- | Run a 'MapReduce' job.  Its result is consumed via a strict left
+-- fold.
+mapReduce :: Connection -> Job -> (a -> MapReduce -> a) -> a -> IO a
+mapReduce conn job f z0 = loop z0 =<< (exchange conn . Req.mapReduce $ job)
+  where
+    loop z mr = do
+      let !z' = f z mr
+      if fromMaybe False . MapReduce.done $ mr
+        then return z'
+        else loop z' =<< recvResponse conn
+        
