on master help sign in
improve docs for ToJSONKey
commitc159831b0c2f7e338925affd935676d91a5c1989 authorAndrew Martin <amartin@layer3com.com> dateThu 9 Jun 2016, 08:46 (10 years ago) parentae2dcc8
1 file changed+30−4
Data/Aeson/Types/ToJSON.hs+30−4
Data/Aeson/Types/ToJSON.hs+30−4
@@ -381,16 +381,14 @@ instance KeyValue Pair where
381381--
382382-- Simple sum types are a final case worth considering. Suppose we have:
383383--
384−-- > data Color = Red | Green | Blue | Black
384+-- > data Color = Red | Green | Blue
385385-- > deriving (Show,Read,Eq,Ord)
386386--
387387-- It is possible to get the 'ToJSONKey' instance for free as we did
388388-- with 'Foo'. However, in this case, we have a natural way to go to
389389-- and from 'Text' that does not require any escape sequences. So, in
390390-- this example, 'ToJSONKeyText' will be used instead of 'ToJSONKeyValue'.
391−-- At the moment, there are no conveniences for this situation. The
392−-- 'Show' instance can be used to help write 'ToJSONKey', but this will
393−-- be inefficient since it uses 'String' as an intermediate step:
391+-- The 'Show' instance can be used to help write 'ToJSONKey':
394392--
395393-- > instance ToJSONKey Color where
396394-- > toJSONKey = ToJSONKeyText f g
@@ -398,6 +396,34 @@ instance KeyValue Pair where
398396-- > g = text . Text.pack . show
399397-- > -- text function is from Data.Aeson.Encoding
400398--
399+-- The situation of needing to turning function @a -> Text@ into
400+-- a 'ToJSONKeyFunction' is common enough that a special combinator
401+-- is provided for it. The above instance can be rewritten as:
402+--
403+-- > instance ToJSONKey Color where
404+-- > toJSONKey = toJSONKeyText (Text.pack . show)
405+--
406+-- The performance of the above instance can be improved by
407+-- not using 'String' as an intermediate step when converting to
408+-- 'Text'. One option for improving performance would be to use
409+-- template haskell machinery from the @text-show@ package. However,
410+-- even with the approach, the 'Encoding' (a wrapper around a bytestring
411+-- builder) is generated by encoding the 'Text' to a 'ByteString',
412+-- an intermediate step that could be avoided. The fastest possible
413+-- implementation would be:
414+--
415+-- > -- Assuming that OverloadedStrings is enabled
416+-- > instance ToJSONKey Color where
417+-- > toJSONKey = ToJSONKeyText f g
418+-- > where f x = case x of {Red -> "Red";Green ->"Green";Blue -> "Blue"}
419+-- > g x = case x of {Red -> text "Red";Green -> text "Green";Blue -> text "Blue"}
420+-- > -- text function is from Data.Aeson.Encoding
421+--
422+-- This works because GHC can lift the encoded values out of the case
423+-- statements, which means that they are only evaluated once. This
424+-- approach should only be used when there is a serious need to
425+-- maximize performance.
426+
401427class ToJSONKey a where
402428 -- | Provides a way to use a data type as the key for a map-like
403429 -- container.