on master help sign in
Finish docs for ToJSONKey
commitae2dcc84fbd7bf8737b00c151665606e39a3b875 authorAndrew Martin <andrew.thaddeus@gmail.com> dateTue 7 Jun 2016, 20:51 (10 years ago) parent0a9674d
1 file changed+51−1
Data/Aeson/Types/ToJSON.hs+51−1
Data/Aeson/Types/ToJSON.hs+51−1
@@ -346,8 +346,58 @@ instance KeyValue Pair where
346346-- >>> LBC8.putStrLn $ encode $ Map.fromList [(["foo","bar","baz" :: Text], 'a')]
347347-- [[["foo","bar","baz"],"a"]]
348348--
349−-- The default implementation of 'ToJSONKey' will choose this method of
349+-- The default implementation of 'ToJSONKey' chooses this method of
350350-- encoding a key, using the 'ToJSON' instance of the type.
351+--
352+-- To use your own data type as the key in a map, all that is needed
353+-- is to write a 'ToJSONKey' (and possibly a 'FromJSONKey') instance
354+-- for it. If the type cannot be trivially converted to and from 'Text',
355+-- it is recommended that 'ToJSONKeyValue' is used. Since the default
356+-- implementations of the typeclass methods can build this from a
357+-- 'ToJSON' instance, there is nothing that needs to be written:
358+--
359+-- > data Foo = Foo { fooAge :: Int, fooName :: Text }
360+-- > deriving (Eq,Ord,Generic)
361+-- > instance ToJSON Foo
362+-- > instance ToJSONKey Foo
363+--
364+-- That's it. We can now write:
365+--
366+-- >>> let m = Map.fromList [(Foo 4 "bar",'a'),(Foo 6 "arg",'b')]
367+-- >>> LBC8.putStrLn $ encode m
368+-- [[{"fooName":"bar","fooAge":4},"a"],[{"fooName":"arg","fooAge":6},"b"]]
369+--
370+-- The next case to consider is if we have a type that is a
371+-- newtype wrapper around 'Text'. The recommended approach is to use
372+-- generalized newtype deriving:
373+--
374+-- > newtype RecordId = RecordId { getRecordId :: Text}
375+-- > deriving (Eq,Ord,ToJSONKey)
376+--
377+-- Then we may write:
378+--
379+-- >>> LBC8.putStrLn $ encode $ Map.fromList [(RecordId "abc",'a')]
380+-- {"abc":"a"}
381+--
382+-- Simple sum types are a final case worth considering. Suppose we have:
383+--
384+-- > data Color = Red | Green | Blue | Black
385+-- > deriving (Show,Read,Eq,Ord)
386+--
387+-- It is possible to get the 'ToJSONKey' instance for free as we did
388+-- with 'Foo'. However, in this case, we have a natural way to go to
389+-- and from 'Text' that does not require any escape sequences. So, in
390+-- 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:
394+--
395+-- > instance ToJSONKey Color where
396+-- > toJSONKey = ToJSONKeyText f g
397+-- > where f = Text.pack . show
398+-- > g = text . Text.pack . show
399+-- > -- text function is from Data.Aeson.Encoding
400+--
351401class ToJSONKey a where
352402 -- | Provides a way to use a data type as the key for a map-like
353403 -- container.