diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,11 @@
 `postgresql-simple-named` uses [PVP Versioning][1].
 The changelog is available [on GitHub][2].
 
+## 0.0.1.0 — Jul 23, 2019
+
+* [#16](https://github.com/holmusk/postgresql-simple-named/issues/16):
+  Implement `queryWithNamed`.
+
 ## 0.0.0.0 — Jul 11, 2019
 
 * Initially created.
diff --git a/postgresql-simple-named.cabal b/postgresql-simple-named.cabal
--- a/postgresql-simple-named.cabal
+++ b/postgresql-simple-named.cabal
@@ -1,13 +1,13 @@
 cabal-version:       2.4
 name:                postgresql-simple-named
-version:             0.0.0.0
+version:             0.0.1.0
 synopsis:            Implementation of named parameters for `postgresql-simple` library
 description:
     Implementation of named parameters for @postgresql-simple@ library.
     .
     Here is an exaple of how it could be used in your code:
     .
-    > queryNamed [sql|
+    > queryNamed dbConnection [sql|
     >     SELECT *
     >     FROM table
     >     WHERE foo = ?foo
@@ -21,7 +21,7 @@
 bug-reports:         https://github.com/Holmusk/postgresql-simple-named/issues
 license:             MPL-2.0
 license-file:        LICENSE
-author:              Dmitrii Kovanikov, Veronika Romashkina
+author:              Veronika Romashkina, Dmitrii Kovanikov
 maintainer:          Holmusk <tech@holmusk.com>
 copyright:           2019 Holmusk
 category:            Database, PostgreSQL
diff --git a/src/PgNamed.hs b/src/PgNamed.hs
--- a/src/PgNamed.hs
+++ b/src/PgNamed.hs
@@ -1,6 +1,5 @@
-{-# LANGUAGE DerivingStrategies        #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE FlexibleContexts   #-}
 
 {- | Introduces named parameters for @postgresql-simple@ library.
 It uses @?@ question mark symbol as the indicator of the named parameter which
@@ -9,12 +8,12 @@
 Check out the example of usage:
 
 @
-'queryNamed' [sql|
-    SELECT *
-    FROM users
-    WHERE foo = ?foo
-      AND bar = ?bar
-      AND baz = ?foo
+'queryNamed' dbConnection [sql|
+    __SELECT__ *
+    __FROM__ users
+    __WHERE__ foo = ?foo
+      __AND__ bar = ?bar
+      __AND__ baz = ?foo
 |] [ "foo" '=?' "fooBar"
    , "bar" '=?' "barVar"
    ]
@@ -37,7 +36,11 @@
 
          -- * Database querying functions with named parameters
        , queryNamed
+       , queryWithNamed
        , executeNamed
+
+         -- * Internal utils
+       , withNamedArgs
        ) where
 
 import Control.Monad.Except (MonadError (throwError))
@@ -54,6 +57,7 @@
 
 import qualified Data.ByteString.Char8 as BS
 import qualified Database.PostgreSQL.Simple as PG
+import qualified Database.PostgreSQL.Simple.FromRow as PG
 import qualified Database.PostgreSQL.Simple.ToField as PG
 import qualified Database.PostgreSQL.Simple.Types as PG
 
@@ -67,7 +71,7 @@
 data NamedParam = NamedParam
     { namedParamName  :: !Name
     , namedParamParam :: !PG.Action
-    } deriving (Show)
+    } deriving stock (Show)
 
 -- | @PostgreSQL@ error type for named parameters.
 data PgNamedError
@@ -77,7 +81,7 @@
     | PgNoNames PG.Query
     -- | Query contains an empty name.
     | PgEmptyName PG.Query
-  deriving (Eq)
+    deriving stock (Eq)
 
 
 -- | Type alias for monads that can throw errors of the 'PgNamedError' type.
@@ -98,7 +102,7 @@
 {- | This function takes query with named parameters specified like this:
 
 @
-SELECT name, user FROM users WHERE id = ?id
+__SELECT__ name, user __FROM__ users __WHERE__ id = ?id
 @
 
 and returns either the error or the query with all names replaced by
@@ -157,10 +161,14 @@
 So it can be used in creating the list of the named arguments:
 
 @
-queryNamed [sql|
-  SELECT * FROM users WHERE foo = ?foo AND bar = ?bar AND baz = ?foo"
-|] [ "foo" =? "fooBar"
-   , "bar" =? "barVar"
+'queryNamed' dbConnection [sql|
+    __SELECT__ *
+    __FROM__ users
+    __WHERE__ foo = ?foo
+      __AND__ bar = ?bar
+      __AND__ baz = ?foo
+|] [ "foo" '=?' "fooBar"
+   , "bar" '=?' "barVar"
    ]
 @
 -}
@@ -173,9 +181,10 @@
 and expects a list of rows in return.
 
 @
-queryNamed dbConnection [sql|
-    SELECT id FROM table
-    WHERE foo = ?foo
+'queryNamed' dbConnection [sql|
+    __SELECT__ id
+    __FROM__ table
+    __WHERE__ foo = ?foo
 |] [ "foo" '=?' "bar" ]
 @
 -}
@@ -189,14 +198,59 @@
     withNamedArgs qNamed params >>= \(q, actions) ->
         liftIO $ PG.query conn q (toList actions)
 
+{- | Queries the database with a given row parser, 'PG.Query', and named parameters
+and expects a list of rows in return.
+
+Sometimes there are multiple ways to parse tuples returned by PostgreSQL into
+the same data type. However, it's not possible to implement multiple intances of
+the 'PG.FromRow' typeclass (or any other typeclass).
+
+Consider the following data type:
+
+@
+__data__ Person = Person
+    { personName :: !Text
+    , personAge  :: !(Maybe Int)
+    }
+@
+
+We might want to parse values of the @Person@ data type in two ways:
+
+1. Default by parsing all fields.
+2. Parse only name and @age@ to 'Nothing'.
+
+If you want to have multiple instances, you need to create @newtype@ for each
+case. However, in some cases it might not be convenient to deal with newtypes
+around large data types. So you can implement custom 'PG.RowParser' and use it
+with 'queryWithNamed'.
+
+@
+'queryWithNamed' rowParser dbConnection [sql|
+    __SELECT__ id
+    __FROM__ table
+    __WHERE__ foo = ?foo
+|] [ "foo" '=?' "bar" ]
+@
+-}
+queryWithNamed
+    :: (MonadIO m, WithNamedError m)
+    => PG.RowParser res -- ^ Custom defined row parser
+    -> PG.Connection    -- ^ Database connection
+    -> PG.Query         -- ^ Query with named parameters inside
+    -> [NamedParam]     -- ^ The list of named parameters to be used in the query
+    -> m [res]          -- ^ Resulting rows
+queryWithNamed rowParser conn qNamed params =
+    withNamedArgs qNamed params >>= \(q, actions) ->
+        liftIO $ PG.queryWith rowParser conn q (toList actions)
+
 {- | Modifies the database with a given query and named parameters
 and expects a number of the rows affected.
 
 @
-executeNamed dbConnection [sql|
-    UPDATE table
-    SET foo = 'bar'
-    WHERE id = ?id
+'executeNamed' dbConnection [sql|
+    __UPDATE__ table
+    __SET__ foo = \'bar\'
+    __WHERE__ id = ?id
 |] [ "id" '=?' someId ]
 @
 -}
@@ -210,7 +264,13 @@
     withNamedArgs qNamed params >>= \(q, actions) ->
         liftIO $ PG.execute conn q (toList actions)
 
--- | Helper to use named parameters.
+{- | Helper to use named parameters. Use it to implement named wrappers around
+functions from @postgresql-simple@ library. If you think that the function is
+useful, consider opening feature request to the @postgresql-simple-named@
+library:
+
+* https://github.com/Holmusk/postgresql-simple-named/issues
+-}
 withNamedArgs
     :: WithNamedError m
     => PG.Query
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveAnyClass     #-}
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE FlexibleContexts   #-}
 
 module Main (main) where
 
@@ -10,10 +11,11 @@
 import System.IO (hSetEncoding, stderr, stdout, utf8)
 import Test.Hspec (Spec, describe, hspec, it, shouldReturn)
 
-import PgNamed (NamedParam, PgNamedError (..), queryNamed, (=?))
+import PgNamed (NamedParam, PgNamedError (..), queryNamed, queryWithNamed, (=?))
 
 import qualified Data.Pool as Pool
 import qualified Database.PostgreSQL.Simple as Sql
+import qualified Database.PostgreSQL.Simple.FromRow as Sql
 
 
 connectionSettings :: ByteString
@@ -36,6 +38,8 @@
         emptyName `shouldReturn` Left (PgEmptyName "SELECT ?foo, ?")
     it "named parameters are parsed and passed correctly" $
         queryTestValue `shouldReturn` Right (TestValue 42 42 "baz")
+    it "named parameters are parsed correctly by user defined row parser" $
+        queryWithTestValue `shouldReturn` Right (TestValue 42 42 "baz")
   where
     missingNamedParam :: IO (Either PgNamedError TestValue)
     missingNamedParam = run "SELECT ?foo, ?bar" ["foo" =? True]
@@ -52,9 +56,29 @@
         , "txtVal" =? ("baz" :: ByteString)
         ]
 
+    queryWithTestValue :: IO (Either PgNamedError TestValue)
+    queryWithTestValue = runWith testValueParser "SELECT ?intVal, ?intVal, ?txtVal"
+        [ "intVal" =? (42 :: Int)
+        , "txtVal" =? ("baz" :: ByteString)
+        ]
+
     run :: Sql.Query -> [NamedParam] -> IO (Either PgNamedError TestValue)
-    run q params = runNamedQuery $ Pool.withResource dbPool (\conn -> queryNamed conn q params)
+    run = callQuery queryNamed
 
+    runWith
+        :: Sql.RowParser TestValue
+        -> Sql.Query
+        -> [NamedParam]
+        -> IO (Either PgNamedError TestValue)
+    runWith rowParser = callQuery (queryWithNamed rowParser)
+
+    callQuery
+        :: (Sql.Connection -> Sql.Query -> [NamedParam] -> ExceptT PgNamedError IO [TestValue])
+        -> Sql.Query
+        -> [NamedParam]
+        -> IO (Either PgNamedError TestValue)
+    callQuery f q params = runNamedQuery $ Pool.withResource dbPool (\conn -> f conn q params)
+
 runNamedQuery :: ExceptT PgNamedError IO [TestValue] -> IO (Either PgNamedError TestValue)
 runNamedQuery = fmap (second head) . runExceptT
 
@@ -64,3 +88,10 @@
     , txtVal  :: !ByteString
     } deriving stock (Show, Eq, Generic)
       deriving anyclass (Sql.FromRow, Sql.ToRow)
+
+testValueParser :: Sql.RowParser TestValue
+testValueParser = do
+    intVal1 <- Sql.field
+    intVal2 <- Sql.field
+    txtVal  <- Sql.field
+    return TestValue{..}
