diff --git a/benchmarks/Main.hs b/benchmarks/Main.hs
--- a/benchmarks/Main.hs
+++ b/benchmarks/Main.hs
@@ -51,7 +51,7 @@
 sessionWithManyLargeResults =
   replicateM 1000 (B.statement () statementWithManyRowsInVector)
 
-sessionWithSingleLargeResultInList :: B.Session (List (Int64, Int64))
+sessionWithSingleLargeResultInList :: B.Session [(Int64, Int64)]
 sessionWithSingleLargeResultInList =
   B.statement () statementWithManyRowsInList
 
@@ -102,6 +102,6 @@
 statementWithManyRowsInVector =
   statementWithManyRows D.rowVector
 
-statementWithManyRowsInList :: C.Statement () (List (Int64, Int64))
+statementWithManyRowsInList :: C.Statement () [(Int64, Int64)]
 statementWithManyRowsInList =
   statementWithManyRows D.rowList
diff --git a/hasql.cabal b/hasql.cabal
--- a/hasql.cabal
+++ b/hasql.cabal
@@ -1,5 +1,5 @@
 name: hasql
-version: 1.4.1
+version: 1.4.2
 category: Hasql, Database, PostgreSQL
 synopsis: An efficient PostgreSQL driver with a flexible mapping API
 description:
diff --git a/library/Hasql/Private/Decoders.hs b/library/Hasql/Private/Decoders.hs
--- a/library/Hasql/Private/Decoders.hs
+++ b/library/Hasql/Private/Decoders.hs
@@ -50,6 +50,9 @@
 singleRow :: Row a -> Result a
 singleRow (Row row) = Result (Results.single (Result.single row))
 
+refineResult :: (a -> Either Text b) -> Result a -> Result b
+refineResult refiner (Result results) = Result (Results.refine refiner results)
+
 -- ** Multi-row traversers
 -------------------------
 
diff --git a/library/Hasql/Private/Decoders/Results.hs b/library/Hasql/Private/Decoders/Results.hs
--- a/library/Hasql/Private/Decoders/Results.hs
+++ b/library/Hasql/Private/Decoders/Results.hs
@@ -82,3 +82,8 @@
           where
             checkErrors =
               ExceptT $ fmap (mapLeft ResultError) $ Result.run Result.noResult (integerDatetimes, result)
+
+refine :: (a -> Either Text b) -> Results a -> Results b
+refine refiner results = Results $ ReaderT $ \ env -> ExceptT $ do
+  resultEither <- run results env
+  return $ resultEither >>= mapLeft (ResultError . UnexpectedResult) . refiner
diff --git a/library/Hasql/Private/Decoders/Row.hs b/library/Hasql/Private/Decoders/Row.hs
--- a/library/Hasql/Private/Decoders/Row.hs
+++ b/library/Hasql/Private/Decoders/Row.hs
@@ -1,6 +1,6 @@
 module Hasql.Private.Decoders.Row where
 
-import Hasql.Private.Prelude
+import Hasql.Private.Prelude hiding (error)
 import Hasql.Private.Errors
 import qualified Database.PostgreSQL.LibPQ as LibPQ
 import qualified PostgreSQL.Binary.Decoding as A
diff --git a/library/Hasql/Private/Errors.hs b/library/Hasql/Private/Errors.hs
--- a/library/Hasql/Private/Errors.hs
+++ b/library/Hasql/Private/Errors.hs
@@ -19,7 +19,9 @@
 -- Comes packed with the query template and a textual representation of the provided params.
 data QueryError =
   QueryError ByteString [Text] CommandError
-  deriving (Show, Eq)
+  deriving (Show, Eq, Typeable)
+
+instance Exception QueryError
 
 -- |
 -- An error of some command in the session.
diff --git a/library/Hasql/Private/Prelude.hs b/library/Hasql/Private/Prelude.hs
--- a/library/Hasql/Private/Prelude.hs
+++ b/library/Hasql/Private/Prelude.hs
@@ -17,7 +17,7 @@
 
 -- base-prelude
 -------------------------
-import BasePrelude as Exports hiding (assert, left, right, isLeft, isRight, fromLeft, fromRight, error, (<>), First(..), Last(..), new)
+import BasePrelude as Exports hiding (assert, left, right, isLeft, isRight, fromLeft, fromRight, (<>), First(..), Last(..), new)
 
 -- transformers
 -------------------------
diff --git a/library/Hasql/Statement.hs b/library/Hasql/Statement.hs
--- a/library/Hasql/Statement.hs
+++ b/library/Hasql/Statement.hs
@@ -1,6 +1,7 @@
 module Hasql.Statement
 (
   Statement(..),
+  refineResult,
   -- * Recipies
 
   -- ** Insert many
@@ -14,6 +15,7 @@
 import Hasql.Private.Prelude
 import qualified Hasql.Decoders as Decoders
 import qualified Hasql.Encoders as Encoders
+import qualified Hasql.Private.Decoders as Decoders
 
 {-|
 Specification of a strictly single-statement query, which can be parameterized and prepared.
@@ -59,6 +61,17 @@
   {-# INLINE dimap #-}
   dimap f1 f2 (Statement template encoder decoder preparable) =
     Statement template (contramap f1 encoder) (fmap f2 decoder) preparable
+
+{-|
+Refine a result of a statement,
+causing the running session to fail with the `UnexpectedResult` error in case of refinement failure.
+
+This function is especially useful for refining the results of statements produced with
+<http://hackage.haskell.org/package/hasql-th the \"hasql-th\" library>.
+-}
+refineResult :: (a -> Either Text b) -> Statement params a -> Statement params b
+refineResult refiner (Statement template encoder decoder preparable) =
+  Statement template encoder (Decoders.refineResult refiner decoder) preparable
 
 
 {- $insertMany
diff --git a/profiling/Main.hs b/profiling/Main.hs
--- a/profiling/Main.hs
+++ b/profiling/Main.hs
@@ -42,7 +42,7 @@
 sessionWithSingleLargeResultInVector =
   B.statement () statementWithManyRowsInVector
 
-sessionWithSingleLargeResultInList :: B.Session (List (Int64, Int64))
+sessionWithSingleLargeResultInList :: B.Session [(Int64, Int64)]
 sessionWithSingleLargeResultInList =
   B.statement () statementWithManyRowsInList
 
@@ -93,6 +93,6 @@
 statementWithManyRowsInVector =
   statementWithManyRows D.rowVector
 
-statementWithManyRowsInList :: C.Statement () (List (Int64, Int64))
+statementWithManyRowsInList :: C.Statement () [(Int64, Int64)]
 statementWithManyRowsInList =
   statementWithManyRows D.rowList
diff --git a/tasty/Main/Prelude.hs b/tasty/Main/Prelude.hs
--- a/tasty/Main/Prelude.hs
+++ b/tasty/Main/Prelude.hs
@@ -1,6 +1,7 @@
 module Main.Prelude
 (
   module Exports,
+  mapLeft,
 )
 where
 
@@ -8,3 +9,8 @@
 -- rerebase
 -------------------------
 import Prelude as Exports
+
+{-# INLINE mapLeft #-}
+mapLeft :: (a -> c) -> Either a b -> Either c b
+mapLeft f =
+  either (Left . f) Right
