Skip to content

Commit d591472

Browse files
author
Lennart Spitzner
committed
Reword To/FromJSON documentation
1 parent 3e0e302 commit d591472

File tree

2 files changed

+29
-45
lines changed

2 files changed

+29
-45
lines changed

Data/Aeson/Types/FromJSON.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,9 @@ genericLiftParseJSON opts pj pjl = fmap to1 . gParseJSON opts (From1Args pj pjl)
346346
-- instance 'FromJSON' Coord
347347
-- @
348348
--
349-
-- If the default implementation doesn't give exactly the results you want,
350-
-- you can customize the generic decoding with only a tiny amount of
351-
-- effort, using 'genericParseJSON' with your preferred 'Options':
349+
-- The default implementation will be equivalent to
350+
-- @parseJSON = 'genericParseJSON' 'defaultOptions'@; If you need different
351+
-- options, you can customize the generic decoding by defining:
352352
--
353353
-- @
354354
-- customOptions = 'defaultOptions'

Data/Aeson/Types/ToJSON.hs

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
205205

206206
-- | A type that can be converted to JSON.
207207
--
208+
-- Instances in general /must/ specify 'toJSON' and /should/ (but don't need
209+
-- to) specify 'toEncoding'.
210+
--
208211
-- An example type and instance:
209212
--
210213
-- @
@@ -230,11 +233,9 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
230233
-- 'toJSON'.
231234
--
232235
-- 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):
238239
--
239240
-- @
240241
-- {-\# LANGUAGE DeriveGeneric \#-}
@@ -247,26 +248,8 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
247248
-- 'toEncoding' = 'genericToEncoding' 'defaultOptions'
248249
-- @
249250
--
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:
270253
--
271254
-- @
272255
-- customOptions = 'defaultOptions'
@@ -278,23 +261,24 @@ genericLiftToEncoding opts te tel = gToEncoding opts (To1Args te tel) . from1
278261
-- 'toEncoding' = 'genericToEncoding' customOptions
279262
-- @
280263
--
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.)
298282
class ToJSON a where
299283
-- | Convert a Haskell value to a JSON-friendly intermediate type.
300284
toJSON :: a -> Value

0 commit comments

Comments
 (0)