diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,9 @@
+## Version 0.5.4.0
+
+ * Add `decodeWithP` and `decodeByNameWithP` to `Streaming` interface ([PR #237](https://github.com/haskell-hvr/cassava/pull/237)).
+ * Build tested with GHC 8.0 - 9.12.2.
+ * Functionality tested with GHC 8.4 - 9.12.2.
+
 ## Version 0.5.3.2
 
  * Proper exception on hanging doublequote ([PR #222](https://github.com/haskell-hvr/cassava/pull/222)).
diff --git a/cassava.cabal b/cassava.cabal
--- a/cassava.cabal
+++ b/cassava.cabal
@@ -1,6 +1,6 @@
 cabal-version:       1.12
 Name:                cassava
-Version:             0.5.3.2
+Version:             0.5.4.0
 Synopsis:            A CSV parsing and encoding library
 Description: {
 
@@ -43,9 +43,10 @@
                      CHANGES.md,
                      README.md
 Tested-with:
-  GHC == 9.10.1
-  GHC == 9.8.2
-  GHC == 9.6.6
+  GHC == 9.12.2
+  GHC == 9.10.2
+  GHC == 9.8.4
+  GHC == 9.6.7
   GHC == 9.4.8
   GHC == 9.2.8
   GHC == 9.0.2
@@ -102,7 +103,7 @@
     , array        >= 0.4      && < 0.6
     , attoparsec   >= 0.11.3.0 && < 0.15
     , bytestring   >= 0.10.4   && < 0.13
-    , containers   >= 0.4.2    && < 0.8
+    , containers   >= 0.4.2    && < 1
     , deepseq      >= 1.1      && < 1.6
     , hashable                    < 2
     , scientific   >= 0.3.4.7  && < 0.4
diff --git a/src/Data/Csv/Streaming.hs b/src/Data/Csv/Streaming.hs
--- a/src/Data/Csv/Streaming.hs
+++ b/src/Data/Csv/Streaming.hs
@@ -21,11 +21,13 @@
     , HasHeader(..)
     , decode
     , decodeWith
+    , decodeWithP
 
     -- ** Name-based record conversion
     -- $namebased
     , decodeByName
     , decodeByNameWith
+    , decodeByNameWithP
     ) where
 
 import Control.DeepSeq (NFData(rnf))
@@ -36,8 +38,9 @@
 import Prelude hiding (foldr)
 
 import Data.Csv.Conversion
+import qualified Data.Csv.Conversion as Conversion
 import Data.Csv.Incremental hiding (decode, decodeByName, decodeByNameWith,
-                                    decodeWith)
+                                    decodeByNameWithP, decodeWith, decodeWithP)
 import qualified Data.Csv.Incremental as I
 import Data.Csv.Parser
 import Data.Csv.Types
@@ -134,8 +137,19 @@
                              -- skipped
            -> BL.ByteString  -- ^ CSV data
            -> Records a
-decodeWith !opts hasHeader s0 =
-    go (BL.toChunks s0) (I.decodeWith opts hasHeader)
+decodeWith = decodeWithP parseRecord
+
+-- | Like 'decodeWith', but lets you specify a parser function.
+--
+-- @since 0.5.4.0
+decodeWithP :: (Record -> Conversion.Parser a)
+           -> DecodeOptions  -- ^ Decoding options
+           -> HasHeader      -- ^ Data contains header that should be
+                             -- skipped
+           -> BL.ByteString  -- ^ CSV data
+           -> Records a
+decodeWithP _parseRecord !opts hasHeader s0 =
+    go (BL.toChunks s0) (I.decodeWithP _parseRecord opts hasHeader)
   where
     go ss (Done xs)       = foldr Cons (Nil Nothing (BL.fromChunks ss)) xs
     go ss (Fail rest err) = Nil (Just err) (BL.fromChunks (rest:ss))
@@ -159,7 +173,18 @@
                  => DecodeOptions  -- ^ Decoding options
                  -> BL.ByteString  -- ^ CSV data
                  -> Either String (Header, Records a)
-decodeByNameWith !opts s0 = go (BL.toChunks s0) (I.decodeByNameWith opts)
+decodeByNameWith = decodeByNameWithP parseNamedRecord
+
+-- | Like 'decodeByNameWith', but lets you specify a parser function.
+--
+-- @since 0.5.4.0
+decodeByNameWithP :: (NamedRecord -> Conversion.Parser a)
+                  -- ^ Custom parser function
+                 -> DecodeOptions  -- ^ Decoding options
+                 -> BL.ByteString  -- ^ CSV data
+                 -> Either String (Header, Records a)
+decodeByNameWithP _parseNamedRecord !opts s0 =
+  go (BL.toChunks s0) (I.decodeByNameWithP _parseNamedRecord opts)
   where
     go ss (DoneH hdr p)    = Right (hdr, go2 ss p)
     go ss (FailH rest err) = Left $ err ++ " at " ++
