@@ -50,6 +50,8 @@ module Data.Aeson.Types.ToJSON
5050 , contramapToJSONKeyFunction
5151 -- * Object key-value pairs
5252 , KeyValue(..)
53+ , KeyValuePair(..)
54+ , FromPairs(..)
5355 -- * Functions needed for documentation
5456 -- * Encoding functions
5557 , listEncoding
@@ -853,14 +855,14 @@ instance ( IsRecord a isRecord
853855 , TaggedObject' enc pairs arity a isRecord
854856 , FromPairs enc pairs
855857 , FromString enc
856− , GKeyValue enc pairs
858+ , KeyValuePair enc pairs
857859 , Constructor c
858860 ) => TaggedObject enc arity (C1 c a)
859861 where
860862 taggedObject opts targs tagFieldName contentsFieldName =
861863 fromPairs . (tag <>) . contents
862864 where
863− tag = tagFieldName `gPair`
865+ tag = tagFieldName `pair`
864866 (fromString (constructorTagModifier opts (conName (undefined :: t c a p)))
865867 :: enc)
866868 contents =
@@ -872,11 +874,11 @@ class TaggedObject' enc pairs arity f isRecord where
872874 -> String -> f a -> Tagged isRecord pairs
873875
874876instance ( GToJSON enc arity f
875− , GKeyValue enc pairs
877+ , KeyValuePair enc pairs
876878 ) => TaggedObject' enc pairs arity f False
877879 where
878880 taggedObject' opts targs contentsFieldName =
879− Tagged . (contentsFieldName `gPair`) . gToJSON opts targs
881+ Tagged . (contentsFieldName `pair`) . gToJSON opts targs
880882
881883instance OVERLAPPING_ Monoid pairs => TaggedObject' enc pairs arity U1 False where
882884 taggedObject' _ _ _ _ = Tagged mempty
@@ -1005,7 +1007,7 @@ instance ( Monoid pairs
10051007
10061008instance ( Selector s
10071009 , GToJSON enc arity a
1008− , GKeyValue enc pairs
1010+ , KeyValuePair enc pairs
10091011 ) => RecordToPairs enc pairs arity (S1 s a)
10101012 where
10111013 recordToPairs = fieldToPair
@@ -1014,7 +1016,7 @@ instance ( Selector s
10141016instance INCOHERENT_
10151017 ( Selector s
10161018 , GToJSON enc arity (K1 i (Maybe a))
1017− , GKeyValue enc pairs
1019+ , KeyValuePair enc pairs
10181020 , Monoid pairs
10191021 ) => RecordToPairs enc pairs arity (S1 s (K1 i (Maybe a)))
10201022 where
@@ -1026,7 +1028,7 @@ instance INCOHERENT_
10261028instance INCOHERENT_
10271029 ( Selector s
10281030 , GToJSON enc arity (K1 i (Maybe a))
1029− , GKeyValue enc pairs
1031+ , KeyValuePair enc pairs
10301032 , Monoid pairs
10311033 ) => RecordToPairs enc pairs arity (S1 s (K1 i (Semigroup.Option a)))
10321034 where
@@ -1038,13 +1040,13 @@ instance INCOHERENT_
10381040
10391041fieldToPair :: (Selector s
10401042 , GToJSON enc arity a
1041− , GKeyValue enc pairs)
1043+ , KeyValuePair enc pairs)
10421044 => Options -> ToArgs enc arity p
10431045 -> S1 s a p -> pairs
10441046fieldToPair opts targs m1 =
10451047 let key = fieldLabelModifier opts (selName m1)
10461048 value = gToJSON opts targs (unM1 m1)
1047− in key `gPair` value
1049+ in key `pair` value
10481050{-# INLINE fieldToPair #-}
10491051
10501052--------------------------------------------------------------------------------
@@ -1098,12 +1100,12 @@ instance OVERLAPPABLE_ (GToJSON Encoding arity a) => EncodeProduct arity a where
10981100instance ( GToJSON enc arity a
10991101 , ConsToJSON enc arity a
11001102 , FromPairs enc pairs
1101− , GKeyValue enc pairs
1103+ , KeyValuePair enc pairs
11021104 , Constructor c
11031105 ) => SumToJSON' ObjectWithSingleField enc arity (C1 c a)
11041106 where
11051107 sumToJSON' opts targs =
1106− Tagged . fromPairs . (typ `gPair`) . gToJSON opts targs
1108+ Tagged . fromPairs . (typ `pair`) . gToJSON opts targs
11071109 where
11081110 typ = constructorTagModifier opts $
11091111 conName (undefined :: t c a p)
@@ -2716,20 +2718,24 @@ packChunks lbs =
27162718
27172719--------------------------------------------------------------------------------
27182720
2721+-- | Wrap a list of pairs as an object.
27192722class Monoid pairs => FromPairs enc pairs | enc -> pairs where
27202723 fromPairs :: pairs -> enc
27212724
2722−instance FromPairs Encoding Series where
2725+instance (a ~ Value) => FromPairs (Encoding' a) Series where
27232726 fromPairs = E.pairs
27242727
27252728instance FromPairs Value (DList Pair) where
27262729 fromPairs = object . toList
27272730
2728−class Monoid kv => GKeyValue v kv where
2729− gPair :: String -> v -> kv
2731+-- | Like 'KeyValue' but the value is already converted to JSON
2732+-- ('Value' or 'Encoding'), and the result actually represents lists of pairs
2733+-- so it can be readily concatenated.
2734+class Monoid kv => KeyValuePair v kv where
2735+ pair :: String -> v -> kv
27302736
2731−instance ToJSON v => GKeyValue v (DList Pair) where
2732− gPair k v = DList.singleton (pack k .= v)
2737+instance (v ~ Value) => KeyValuePair v (DList Pair) where
2738+ pair k v = DList.singleton (pack k .= v)
27332739
2734−instance GKeyValue Encoding Series where
2735− gPair = E.pairStr
2740+instance (e ~ Encoding) => KeyValuePair e Series where
2741+ pair = E.pairStr