@@ -205,6 +205,9 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
205
205
206
206
-- | A type that can be converted to JSON.
207
207
--
208
+ -- Instances in general /must/ specify 'toJSON' and /should/ (but don't need
209
+ -- to) specify 'toEncoding'.
210
+ --
208
211
-- An example type and instance:
209
212
--
210
213
-- @
@@ -230,11 +233,9 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
230
233
-- 'toJSON'.
231
234
--
232
235
-- To use the second, simply add a @deriving 'Generic'@ clause to your
233
- -- datatype and declare a 'ToJSON' instance for your datatype without giving
234
- -- definitions for 'toJSON' or 'toEncoding'.
235
- --
236
- -- For example, the previous example can be simplified to a more
237
- -- minimal instance:
236
+ -- datatype and declare a 'ToJSON' instance. If you require nothing other than
237
+ -- 'defaultOptions', it is sufficient to write (and this is the only
238
+ -- alternative where the default 'toJSON' implementation is sufficient):
238
239
--
239
240
-- @
240
241
-- {-\# LANGUAGE DeriveGeneric \#-}
@@ -247,26 +248,8 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
247
248
-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
248
249
-- @
249
250
--
250
- -- Why do we provide an implementation for 'toEncoding' here? The
251
- -- 'toEncoding' function is a relatively new addition to this class.
252
- -- To allow users of older versions of this library to upgrade without
253
- -- having to edit all of their instances or encounter surprising
254
- -- incompatibilities, the default implementation of 'toEncoding' uses
255
- -- 'toJSON'. This produces correct results, but since it performs an
256
- -- intermediate conversion to a 'Value', it will be less efficient
257
- -- than directly emitting an 'Encoding'. Our one-liner definition of
258
- -- 'toEncoding' above bypasses the intermediate 'Value'.
259
- --
260
- -- If the default implementation doesn't give exactly the results you want,
261
- -- you can customize the generic encoding with only a tiny amount of
262
- -- effort, using 'genericToJSON' and 'genericToEncoding' with your
263
- -- preferred 'Options'.
264
- --
265
- -- The following examples ensure that 'toEncoding' represents the same
266
- -- encoding as 'toJSON'.
267
- --
268
- -- - A typical implementation defines both 'toJSON' and 'toEncoding'
269
- -- with the same options.
251
+ -- If on the other hand you wish to customize the generic decoding, you have
252
+ -- to implement both methods:
270
253
--
271
254
-- @
272
255
-- customOptions = 'defaultOptions'
@@ -278,23 +261,24 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
278
261
-- 'toEncoding' = 'genericToEncoding' customOptions
279
262
-- @
280
263
--
281
- -- - A minimal definition of 'ToJSON' is given by 'toJSON'.
282
- -- This is most useful to define an instance manually when
283
- -- the generic options are not satisfactory.
284
- --
285
- -- @
286
- -- instance 'ToJSON' Coord where
287
- -- 'toJSON' (Coord x y) = 'Array' (toJSON [x, y])
288
- -- @
289
- --
290
- -- - The default implementation of 'toJSON' uses 'defaultOptions'. If you leave
291
- -- 'toJSON' implicit while providing a more efficient explicit implementation
292
- -- of 'toEncoding', then it *must* be equivalent to using 'defaultOptions'.
293
- --
294
- -- @
295
- -- instance ToJSON Coord where
296
- -- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
297
- -- @
264
+ -- Previous versions of this library only had the 'toJSON' method. Adding
265
+ -- 'toEncoding' had to reasons:
266
+ --
267
+ -- 1. toEncoding is more efficient for the common case that the output of
268
+ -- 'toJSON' is directly serialized to a @ByteString@.
269
+ -- Further, expressing either method in terms of the other would be
270
+ -- non-optimal.
271
+ --
272
+ -- 2. The choice of defaults allows a smooth transition for existing users:
273
+ -- Existing instances that do not define 'toEncoding' still
274
+ -- compile and have the correct semantics. This is ensured by making
275
+ -- the default implementation of 'toEncoding' use 'toJSON'. This produces
276
+ -- correct results, but since it performs an intermediate conversion to a
277
+ -- 'Value', it will be less efficient than directly emitting an 'Encoding'.
278
+ -- (this also means that specifying nothing more than
279
+ -- @instance ToJSON Coord@ would be sufficient as a generically decoding
280
+ -- instance, but there probably exists no good reason to not specify
281
+ -- 'toEncoding' in new instances.)
298
282
class ToJSON a where
299
283
-- | Convert a Haskell value to a JSON-friendly intermediate type.
300
284
toJSON :: a -> Value
0 commit comments