diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -13,20 +13,6 @@
 
 Hasql is production-ready, actively maintained and the API is moderately stable. It's used by many companies and most notably by the [Postgrest](https://github.com/PostgREST/postgrest) project.
 
-# Support Policy
-
-This policy is intended to balance stability for users with the ability to evolve the library.
-
-Each major release of Hasql is supported for at least **one year** from the date of its first release. During this period, fixes are backported to the latest minor version of that major release.
-
-After the support period ends, the release may continue to work but is no longer guaranteed to receive fixes.
-
-You're welcome to post requests to change the policy or issues if you believe something is not being addressed.
-
-# Discussions
-
-Join [GitHub Discussions](https://github.com/nikita-volkov/hasql/discussions) to ask questions, provide feedback, suggest and vote on features, and help shape the future of Hasql.
-
 # Ecosystem
 
 Hasql is not just a single library, it is a granular ecosystem of composable libraries, each isolated to perform its own task and stay simple.
@@ -209,3 +195,17 @@
       (($1 :: int8) % ($2 :: int8)) :: int8
   |]
 ```
+
+# Discussions
+
+Join [GitHub Discussions](https://github.com/nikita-volkov/hasql/discussions) to ask questions, provide feedback, suggest and vote on features, and help shape the future of Hasql.
+
+# Support Policy
+
+This policy is intended to balance stability for users with the ability to evolve the library.
+
+Each major release of Hasql is supported for at least **one year** from the date of its first release. During this period, fixes are backported to the latest minor version of that major release.
+
+After the support period ends, the release may continue to work but is no longer guaranteed to receive fixes.
+
+You're welcome to post requests to change the policy or issues if you believe something is not being addressed.
diff --git a/hasql.cabal b/hasql.cabal
--- a/hasql.cabal
+++ b/hasql.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: hasql
-version: 1.10.2.1
+version: 1.10.2.2
 category: Hasql, Database, PostgreSQL
 synopsis: Fast PostgreSQL driver with a flexible mapping API
 description:
diff --git a/src/library/Hasql/Codecs/Decoders/Array.hs b/src/library/Hasql/Codecs/Decoders/Array.hs
--- a/src/library/Hasql/Codecs/Decoders/Array.hs
+++ b/src/library/Hasql/Codecs/Decoders/Array.hs
@@ -41,13 +41,13 @@
       -- | Number of dimensions.
       Word
       -- | Decoding function
-      (RequestingOid.RequestingOid Binary.Array a)
+      (RequestingOid.RequestingOid (Binary.Array a))
   deriving (Functor)
 
 {-# INLINE toValueDecoder #-}
-toValueDecoder :: Array a -> RequestingOid.RequestingOid Binary.Value a
+toValueDecoder :: Array a -> RequestingOid.RequestingOid (Binary.Value a)
 toValueDecoder (Array _ _ _ _ _ decoder) =
-  RequestingOid.hoist Binary.array decoder
+  fmap Binary.array decoder
 
 -- | Get the type signature for the array based on element type name
 {-# INLINE toTypeSig #-}
@@ -114,7 +114,7 @@
     baseOid
     arrayOid
     (succ ndims)
-    (RequestingOid.hoist (Binary.dimensionArray replicateM) decoder)
+    (fmap (Binary.dimensionArray replicateM) decoder)
 
 -- |
 -- Lift a 'Value.Value' decoder into an 'Array' decoder for parsing of leaf values.
@@ -128,7 +128,7 @@
       (Value.toBaseOid imp)
       (Value.toArrayOid imp)
       1
-      (RequestingOid.hoist Binary.valueArray (Value.toDecoder imp))
+      (fmap Binary.valueArray (Value.toDecoder imp))
   NullableOrNot.Nullable imp ->
     Array
       (Value.toSchema imp)
@@ -136,4 +136,4 @@
       (Value.toBaseOid imp)
       (Value.toArrayOid imp)
       1
-      (RequestingOid.hoist Binary.nullableValueArray (Value.toDecoder imp))
+      (fmap Binary.nullableValueArray (Value.toDecoder imp))
diff --git a/src/library/Hasql/Codecs/Decoders/Composite.hs b/src/library/Hasql/Codecs/Decoders/Composite.hs
--- a/src/library/Hasql/Codecs/Decoders/Composite.hs
+++ b/src/library/Hasql/Codecs/Decoders/Composite.hs
@@ -9,13 +9,14 @@
 -- |
 -- Composable decoder of composite values (rows, records).
 newtype Composite a
-  = Composite (RequestingOid.RequestingOid Binary.Composite a)
-  deriving newtype
+  = Composite (RequestingOid.RequestingOid (Binary.Composite a))
+  deriving
     (Functor, Applicative)
+    via (Compose RequestingOid.RequestingOid Binary.Composite)
 
-toValueDecoder :: Composite a -> RequestingOid.RequestingOid Binary.Value a
+toValueDecoder :: Composite a -> RequestingOid.RequestingOid (Binary.Value a)
 toValueDecoder (Composite imp) =
-  RequestingOid.hoist Binary.composite imp
+  fmap Binary.composite imp
 
 -- |
 -- Lift a 'Value.Value' decoder into a 'Composite' decoder for parsing of component values.
@@ -26,12 +27,12 @@
         staticOid = if dimensionality == 0 then Value.toBaseOid imp else Value.toArrayOid imp
      in case staticOid of
           Just oid ->
-            Composite (RequestingOid.hoist (Binary.typedValueComposite oid) (Value.toDecoder imp))
+            Composite (fmap (Binary.typedValueComposite oid) (Value.toDecoder imp))
           Nothing ->
             Composite
               ( RequestingOid.hoistLookingUp
                   (Value.toSchema imp, Value.toTypeName imp)
-                  (\(baseOid, arrayOid) -> Binary.typedValueComposite (if dimensionality == 0 then baseOid else arrayOid))
+                  (\(baseOid, arrayOid) decoder -> Binary.typedValueComposite (if dimensionality == 0 then baseOid else arrayOid) decoder)
                   (Value.toDecoder imp)
               )
   NullableOrNot.Nullable imp ->
@@ -39,11 +40,11 @@
         staticOid = if dimensionality == 0 then Value.toBaseOid imp else Value.toArrayOid imp
      in case staticOid of
           Just oid ->
-            Composite (RequestingOid.hoist (Binary.typedNullableValueComposite oid) (Value.toDecoder imp))
+            Composite (fmap (Binary.typedNullableValueComposite oid) (Value.toDecoder imp))
           Nothing ->
             Composite
               ( RequestingOid.hoistLookingUp
                   (Value.toSchema imp, Value.toTypeName imp)
-                  (\(baseOid, arrayOid) -> Binary.typedNullableValueComposite (if dimensionality == 0 then baseOid else arrayOid))
+                  (\(baseOid, arrayOid) decoder -> Binary.typedNullableValueComposite (if dimensionality == 0 then baseOid else arrayOid) decoder)
                   (Value.toDecoder imp)
               )
diff --git a/src/library/Hasql/Codecs/Decoders/Value.hs b/src/library/Hasql/Codecs/Decoders/Value.hs
--- a/src/library/Hasql/Codecs/Decoders/Value.hs
+++ b/src/library/Hasql/Codecs/Decoders/Value.hs
@@ -77,9 +77,11 @@
       -- | Dimensionality. If 0 then it is a scalar value, otherwise it is an array with that many dimensions.
       Word
       -- | Decoding function on a registry of OIDs by type name.
-      (RequestingOid.RequestingOid Binary.Value a)
+      (RequestingOid.RequestingOid (Binary.Value a))
   deriving (Functor)
 
+type role Value representational
+
 instance Filterable Value where
   {-# INLINE mapMaybe #-}
   mapMaybe fn =
@@ -379,7 +381,7 @@
 {-# INLINE refine #-}
 refine :: (a -> Either Text b) -> Value a -> Value b
 refine fn (Value schema typeName typeOid arrayOid dimensionality decoder) =
-  Value schema typeName typeOid arrayOid dimensionality (RequestingOid.hoist (Binary.refine fn) decoder)
+  Value schema typeName typeOid arrayOid dimensionality (fmap (Binary.refine fn) decoder)
 
 -- |
 -- Binary generic decoder of @HSTORE@ values.
@@ -431,7 +433,7 @@
 toArrayOid :: Value a -> Maybe Word32
 toArrayOid (Value _ _ _ oid _ _) = oid
 
-toDecoder :: Value a -> RequestingOid.RequestingOid Binary.Value a
+toDecoder :: Value a -> RequestingOid.RequestingOid (Binary.Value a)
 toDecoder (Value _ _ _ _ _ decoder) = decoder
 
 {-# INLINE toHandler #-}
diff --git a/src/library/Hasql/Codecs/RequestingOid.hs b/src/library/Hasql/Codecs/RequestingOid.hs
--- a/src/library/Hasql/Codecs/RequestingOid.hs
+++ b/src/library/Hasql/Codecs/RequestingOid.hs
@@ -14,6 +14,7 @@
 import Data.HashMap.Strict qualified as HashMap
 import Hasql.Codecs.RequestingOid.LookingUp qualified as LookingUp
 import Hasql.Platform.Prelude hiding (lift, lookup)
+import PostgreSQL.Binary.Decoding qualified as Binary
 
 type RequestingOid =
   LookingUp.LookingUp
@@ -21,15 +22,15 @@
     (Word32, Word32)
 
 toUnknownTypes ::
-  RequestingOid f a ->
+  RequestingOid a ->
   HashSet (Maybe Text, Text)
 toUnknownTypes (LookingUp.LookingUp unknownTypes _) =
   fromList unknownTypes
 
 toBase ::
-  RequestingOid f a ->
+  RequestingOid a ->
   HashMap (Maybe Text, Text) (Word32, Word32) ->
-  f a
+  a
 toBase (LookingUp.LookingUp _unknownTypes decoder) oidCache =
   decoder \key ->
     HashMap.lookup key oidCache
@@ -37,21 +38,21 @@
 
 requestAndHandle ::
   [(Maybe Text, Text)] ->
-  (((Maybe Text, Text) -> (Word32, Word32)) -> f a) ->
-  RequestingOid f a
-requestAndHandle = LookingUp.LookingUp
+  (((Maybe Text, Text) -> (Word32, Word32)) -> a) ->
+  RequestingOid a
+requestAndHandle keys fn = LookingUp.LookingUp keys fn
 
-lift :: f a -> RequestingOid f a
+lift :: a -> RequestingOid a
 lift = LookingUp.lift
 
-hoist :: (f a -> g b) -> RequestingOid f a -> RequestingOid g b
-hoist = LookingUp.hoist
+hoist :: (a -> b) -> RequestingOid a -> RequestingOid b
+hoist fn (LookingUp.LookingUp keys use) = LookingUp.LookingUp keys (fn . use)
 
-lookup :: (Applicative f) => (Maybe Text, Text) -> RequestingOid f (Word32, Word32)
+lookup :: (Maybe Text, Text) -> RequestingOid (Word32, Word32)
 lookup = LookingUp.lookup
 
-lookingUp :: (Applicative f) => (Maybe Text, Text) -> ((Word32, Word32) -> f a) -> RequestingOid f a
+lookingUp :: (Maybe Text, Text) -> ((Word32, Word32) -> a) -> RequestingOid a
 lookingUp = LookingUp.lookingUp
 
-hoistLookingUp :: (Applicative f) => (Maybe Text, Text) -> ((Word32, Word32) -> f a -> g b) -> RequestingOid f a -> RequestingOid g b
+hoistLookingUp :: (Maybe Text, Text) -> ((Word32, Word32) -> a -> b) -> RequestingOid a -> RequestingOid b
 hoistLookingUp = LookingUp.hoistLookingUp
diff --git a/src/library/Hasql/Codecs/RequestingOid/LookingUp.hs b/src/library/Hasql/Codecs/RequestingOid/LookingUp.hs
--- a/src/library/Hasql/Codecs/RequestingOid/LookingUp.hs
+++ b/src/library/Hasql/Codecs/RequestingOid/LookingUp.hs
@@ -4,44 +4,37 @@
 import Witherable
 import Prelude
 
-data LookingUp k v f a
+data LookingUp k v a
   = LookingUp
       -- | Keys requested to be available for lookup.
       [k]
       -- | Continuation that looks up values by keys.
-      ((k -> v) -> f a)
+      ((k -> v) -> a)
 
-deriving instance (Functor f) => Functor (LookingUp k v f)
+type role LookingUp _ _ representational
 
-instance (Applicative f) => Applicative (LookingUp k v f) where
+deriving stock instance Functor (LookingUp k v)
+
+instance Applicative (LookingUp k v) where
   pure a =
-    LookingUp [] (\_ -> pure a)
+    LookingUp [] (\_ -> a)
   LookingUp lKeys lUse <*> LookingUp rKeys rUse =
     LookingUp
       (lKeys <> rKeys)
-      (\lookup -> lUse lookup <*> rUse lookup)
-
-instance (Filterable f) => Filterable (LookingUp k v f) where
-  {-# INLINE mapMaybe #-}
-  mapMaybe fn (LookingUp keys use) =
-    LookingUp keys (mapMaybe fn . use)
+      (\lookup -> lUse lookup (rUse lookup))
 
-lookup :: (Applicative f) => k -> LookingUp k v f v
+lookup :: k -> LookingUp k v v
 lookup key =
-  LookingUp [key] (\lookupFn -> pure (lookupFn key))
+  LookingUp [key] (\lookupFn -> lookupFn key)
 
-lift :: f a -> LookingUp k v f a
+lift :: a -> LookingUp k v a
 lift fa =
   LookingUp [] (const fa)
 
-hoist :: (f a -> g b) -> LookingUp k v f a -> LookingUp k v g b
-hoist tx (LookingUp keys use) =
-  LookingUp keys (tx . use)
-
-lookingUp :: k -> (v -> f a) -> LookingUp k v f a
+lookingUp :: k -> (v -> a) -> LookingUp k v a
 lookingUp key cont =
   LookingUp [key] (\lookupFn -> cont (lookupFn key))
 
-hoistLookingUp :: k -> (v -> f a -> g b) -> LookingUp k v f a -> LookingUp k v g b
+hoistLookingUp :: k -> (v -> a -> b) -> LookingUp k v a -> LookingUp k v b
 hoistLookingUp k tx (LookingUp keys use) =
   LookingUp (k : keys) (\lookupFn -> tx (lookupFn k) (use lookupFn))
diff --git a/src/library/Hasql/Engine/Decoders/Result.hs b/src/library/Hasql/Engine/Decoders/Result.hs
--- a/src/library/Hasql/Engine/Decoders/Result.hs
+++ b/src/library/Hasql/Engine/Decoders/Result.hs
@@ -9,11 +9,12 @@
 -- |
 -- Decoder of a query result.
 newtype Result a
-  = Result (RequestingOid.RequestingOid ResultDecoder.ResultDecoder a)
-  deriving newtype
+  = Result (RequestingOid.RequestingOid (ResultDecoder.ResultDecoder a))
+  deriving
     (Functor, Applicative, Filterable)
+    via (Compose RequestingOid.RequestingOid ResultDecoder.ResultDecoder)
 
-unwrap :: Result a -> RequestingOid.RequestingOid ResultDecoder.ResultDecoder a
+unwrap :: Result a -> RequestingOid.RequestingOid (ResultDecoder.ResultDecoder a)
 unwrap (Result decoder) = decoder
 
 -- * Construction
@@ -41,11 +42,11 @@
 {-# INLINEABLE singleRow #-}
 singleRow :: Row a -> Result a
 singleRow decoder =
-  Result (RequestingOid.hoist ResultDecoder.single (Row.toDecoder decoder))
+  Result (fmap ResultDecoder.single (Row.toDecoder decoder))
 
 refineResult :: (a -> Either Text b) -> Result a -> Result b
 refineResult refiner (Result decoder) =
-  Result (RequestingOid.hoist (ResultDecoder.refine refiner) decoder)
+  Result (fmap (ResultDecoder.refine refiner) decoder)
 
 -- ** Multi-row traversers
 
@@ -55,7 +56,7 @@
 foldlRows :: (a -> b -> a) -> a -> Row b -> Result a
 foldlRows step init decoder =
   Result
-    (RequestingOid.hoist (ResultDecoder.foldl step init) (Row.toDecoder decoder))
+    (fmap (ResultDecoder.foldl step init) (Row.toDecoder decoder))
 
 -- |
 -- Foldr multiple rows.
@@ -63,7 +64,7 @@
 foldrRows :: (b -> a -> a) -> a -> Row b -> Result a
 foldrRows step init decoder =
   Result
-    (RequestingOid.hoist (ResultDecoder.foldr step init) (Row.toDecoder decoder))
+    (fmap (ResultDecoder.foldr step init) (Row.toDecoder decoder))
 
 -- ** Specialized multi-row results
 
@@ -73,7 +74,7 @@
 rowMaybe :: Row a -> Result (Maybe a)
 rowMaybe decoder =
   Result
-    (RequestingOid.hoist ResultDecoder.maybe (Row.toDecoder decoder))
+    (fmap ResultDecoder.maybe (Row.toDecoder decoder))
 
 -- |
 -- Zero or more rows packed into the vector.
@@ -84,7 +85,7 @@
 rowVector :: Row a -> Result (Vector a)
 rowVector decoder =
   Result
-    (RequestingOid.hoist ResultDecoder.vector (Row.toDecoder decoder))
+    (fmap ResultDecoder.vector (Row.toDecoder decoder))
 
 -- |
 -- Zero or more rows packed into the list.
diff --git a/src/library/Hasql/Engine/Decoders/Row.hs b/src/library/Hasql/Engine/Decoders/Row.hs
--- a/src/library/Hasql/Engine/Decoders/Row.hs
+++ b/src/library/Hasql/Engine/Decoders/Row.hs
@@ -17,13 +17,14 @@
 -- x = (,,) '<$>' ('column' . 'nullable') 'int8' '<*>' ('column' . 'nonNullable') 'text' '<*>' ('column' . 'nonNullable') 'time'
 -- @
 newtype Row a
-  = Row (RequestingOid.RequestingOid Hasql.Comms.RowDecoder.RowDecoder a)
-  deriving newtype
+  = Row (RequestingOid.RequestingOid (Hasql.Comms.RowDecoder.RowDecoder a))
+  deriving
     (Functor, Applicative, Filterable)
+    via (Compose RequestingOid.RequestingOid Hasql.Comms.RowDecoder.RowDecoder)
 
 toDecoder ::
   Row a ->
-  RequestingOid.RequestingOid Hasql.Comms.RowDecoder.RowDecoder a
+  RequestingOid.RequestingOid (Hasql.Comms.RowDecoder.RowDecoder a)
 toDecoder (Row f) = f
 
 -- |
@@ -34,26 +35,26 @@
   Nullable valueDecoder ->
     Row case Value.toOid valueDecoder of
       Just oid ->
-        RequestingOid.hoist
+        fmap
           (Hasql.Comms.RowDecoder.nullableColumn (Just oid) . Binary.valueParser)
           (Value.toDecoder valueDecoder)
       Nothing -> do
         RequestingOid.hoistLookingUp
           (Value.toSchema valueDecoder, Value.toTypeName valueDecoder)
-          ( \lookupResult ->
-              Hasql.Comms.RowDecoder.nullableColumn (Just (chooseLookedUpOid valueDecoder lookupResult)) . Binary.valueParser
+          ( \lookupResult decoder ->
+              Hasql.Comms.RowDecoder.nullableColumn (Just (chooseLookedUpOid valueDecoder lookupResult)) (Binary.valueParser decoder)
           )
           (Value.toDecoder valueDecoder)
   NonNullable valueDecoder ->
     Row case Value.toOid valueDecoder of
       Just oid ->
-        RequestingOid.hoist
+        fmap
           (Hasql.Comms.RowDecoder.nonNullableColumn (Just oid) . Binary.valueParser)
           (Value.toDecoder valueDecoder)
       Nothing -> do
         RequestingOid.hoistLookingUp
           (Value.toSchema valueDecoder, Value.toTypeName valueDecoder)
-          (\lookupResult -> Hasql.Comms.RowDecoder.nonNullableColumn (Just (chooseLookedUpOid valueDecoder lookupResult)) . Binary.valueParser)
+          (\lookupResult decoder -> Hasql.Comms.RowDecoder.nonNullableColumn (Just (chooseLookedUpOid valueDecoder lookupResult)) (Binary.valueParser decoder))
           (Value.toDecoder valueDecoder)
   where
     chooseLookedUpOid valueDecoder (elementOid, arrayOid) =
