on master help sign in
Merge pull request #428 from andrewthad/document_fromjsonkey

Add docs for FromJSONKey

commit40b41290a375e3ef83b803558cd1d9181f0ea3cd authorAdam Bergmark <adam@bergmark.nl> dateWed 15 Jun 2016, 17:11 (10 years ago) parent68bb89f652d301
2 files changed+35−8
Data/Aeson/Types/FromJSON.hs+32−5 Data/Aeson/Types/ToJSON.hs+3−3
Data/Aeson/Types/FromJSON.hs+32−5
@@ -323,21 +323,34 @@ class FromJSON a where
323323-- Classes and types for map keys
324324-------------------------------------------------------------------------------
325325
326+-- | Read the docs for 'ToJSONKey' first. This class is a conversion
327+-- in the opposite direction. If you have a newtype wrapper around 'Text',
328+-- the recommended way to define instances is with generalized newtype deriving:
329+--
330+-- > newtype SomeId = SomeId { getSomeId :: Text }
331+-- > deriving (Eq,Ord,Hashable,FromJSONKey)
332+--
326333class FromJSONKey a where
334+ -- | Strategy for parsing the key of a map-like container.
327335 fromJSONKey :: FromJSONKeyFunction a
328336 default fromJSONKey :: FromJSON a => FromJSONKeyFunction a
329337 fromJSONKey = FromJSONKeyValue parseJSON
330338
339+ -- | This is similar in spirit to the 'readList' method of 'Read'.
340+ -- It makes it possible to give 'String' keys special treatment
341+ -- without using @OverlappingInstances@. End users should always
342+ -- be able to use the default implementation of this method.
331343 fromJSONKeyList :: FromJSONKeyFunction [a]
332344 default fromJSONKeyList :: FromJSON a => FromJSONKeyFunction [a]
333345 fromJSONKeyList = FromJSONKeyValue parseJSON
334346
335−-- | With GHC 7.8 + we carry around 'Coercible Text a' dictionary,
336−-- to have even some amount of safety net.
337−-- Unfortunately we cannot enforce that 'Hashable' instance agree on the type level
347+-- | With GHC 7.8+ we carry around @'Coercible' 'Text' a@ dictionary,
348+-- to give us an assurance that the program will not segfault.
349+-- Unfortunately we cannot enforce that the 'Eq' instances or the
350+-- 'Hashable' instances for 'Text' and @a@ agree.
338351--
339−-- ATM this type is intentionally not exported. FromJSONKeyFunction can be inspected,
340−-- but cannot be constructed.
352+-- At the moment this type is intentionally not exported. 'FromJSONKeyFunction'
353+-- can be inspected, but cannot be constructed.
341354data CoerceText a where
342355#if HAS_COERCIBLE
343356 CoerceText :: Coercible Text a => CoerceText a
@@ -345,12 +358,23 @@ data CoerceText a where
345358 CoerceText :: CoerceText a
346359#endif
347360
361+-- | This type is related to 'ToJSONKeyFunction'. If 'FromJSONKeyValue' is used in the
362+-- 'FromJSONKey' instance, then 'ToJSONKeyValue' should be used in the 'ToJSONKey'
363+-- instance. The other three data constructors for this type all correspond to
364+-- 'ToJSONKeyText'. Strictly speaking, 'FromJSONKeyTextParser' is more powerful than
365+-- 'FromJSONKeyText', which is in turn more powerful than 'FromJSONKeyCoerce'.
366+-- For performance reasons, these exist as three options instead of one.
348367data FromJSONKeyFunction a
349368 = FromJSONKeyCoerce !(CoerceText a)
369+ -- ^ uses 'coerce' ('unsafeCoerce' in older GHCs)
350370 | FromJSONKeyText !(Text -> a)
371+ -- ^ conversion from 'Text' that always succeeds
351372 | FromJSONKeyTextParser !(Text -> Parser a)
373+ -- ^ conversion from 'Text' that may fail
352374 | FromJSONKeyValue !(Value -> Parser a)
375+ -- ^ conversion for non-textual keys
353376
377+-- | Only law abiding up to interpretation
354378instance Functor FromJSONKeyFunction where
355379 fmap h (FromJSONKeyCoerce CoerceText) = FromJSONKeyText (h . coerce')
356380 fmap h (FromJSONKeyText f) = FromJSONKeyText (h . f)
@@ -359,6 +383,9 @@ instance Functor FromJSONKeyFunction where
359383
360384-- | Construct 'FromJSONKeyFunction' for types coercible from 'Text'. This
361385-- conversion is still unsafe, as 'Hashable' and 'Eq' instances of @a@ should be
386+-- compatible with 'Text' i.e. hash values should be equal for wrapped values as well.
387+-- This property will always be maintained if the 'Hashable' and 'Eq' instances
388+-- are derived with generalized newtype deriving.
362389-- compatible with 'Text' i.e. hash values be equal for wrapped values as well.
363390--
364391-- On pre GHC 7.8 this is unconstrainted function.
Data/Aeson/Types/ToJSON.hs+3−3
@@ -413,15 +413,15 @@ instance KeyValue Pair where
413413-- maximize performance.
414414
415415class ToJSONKey a where
416− -- | Provides a way to use a data type as the key for a map-like
417− -- container.
416+ -- | Strategy for rendering the key for a map-like container.
418417 toJSONKey :: ToJSONKeyFunction a
419418 default toJSONKey :: ToJSON a => ToJSONKeyFunction a
420419 toJSONKey = ToJSONKeyValue toJSON toEncoding
421420
422421 -- | This is similar in spirit to the 'showsList' method of 'Show'.
423422 -- It makes it possible to give 'String' keys special treatment
424− -- without using @OverlappingInstances@.
423+ -- without using @OverlappingInstances@. End users should always
424+ -- be able to use the default implementation of this method.
425425 toJSONKeyList :: ToJSONKeyFunction [a]
426426 default toJSONKeyList :: ToJSON a => ToJSONKeyFunction [a]
427427 toJSONKeyList = ToJSONKeyValue toJSON toEncoding