@@ -11,136 +11,20 @@
12-- (A note on naming: in Greek mythology, Aeson was the father of Jason.)
12-- (A note on naming: in Greek mythology, Aeson was the father of Jason.)
14−-- /DECODING TO AN ADT ('VALUE')/
16−-- To parse JSON into something useful, everything goes through the
17−-- 'decode' function, which is polymorphic on the 'FromJSON'
18−-- class. For representing arbitrary JSON AST there is a 'Value' type,
19−-- which is an instance of 'FromJSON'. For example:
21−-- > λ> decode "{\"foo\":123}" :: Maybe Value
22−-- > Just (Object (fromList [("foo",Number 123)]))
23−-- > λ> decode "{\"foo\":[\"abc\",\"def\"]}" :: Maybe Value
24−-- > Just (Object (fromList [("foo",Array (fromList [String "abc",String "def"]))]))
26−-- To run these examples, you need to enable @OverloadedStrings@ (in
27−-- GHCi you can write @:set -XOverloadedStrings@) so that you can use
28−-- string literals for non-'String' types. We're using (the lazy
29−-- version of) 'Data.ByteString.Lazy.ByteString', which requires at
30−-- least version 0.9.0.4 of the bytestring package to provide the
31−-- 'Data.String.IsString' instance. You probably have something newer
32−-- than this installed.
34−-- /DECODING TO HASKELL TYPES/
36−-- Any instance of 'FromJSON' can be specified (but see the PITFALLS section):
38−-- > λ> decode "[1,2,3]" :: Maybe [Int]
41−-- Alternatively, there are instances for standard data types, so you
42−-- can use them directly. For example, use the 'Data.Map.Map' type to
43−-- get a map of 'Int's.
46−-- > λ> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
47−-- > Just (fromList [("bar",2),("foo",1)])
49−-- /DECODING A HETEROGENOUS OBJECT/
51−-- The above approach with maps of course will not work for
52−-- heterogenous objects, so there are a couple of approaches available
55−-- The 'Object' type contains JSON objects:
57−-- > λ> decode "{\"name\":\"Dave\",\"age\":2}" :: Maybe Object
58−-- > Just (fromList) [("name",String "Dave"),("age",Number 2)]
60−-- And you extract values from it with a parser using 'parse',
61−-- 'parseEither' or, in this example, 'parseMaybe':
63−-- > λ> do result <- decode "{\"name\":\"Dave\",\"age\":2}"
64−-- > flip parseMaybe result $ \obj -> do
65−-- > age <- obj .: "age"
66−-- > name <- obj .: "name"
67−-- > return (name ++ ": " ++ show (age*2))
71−-- Considering that any type that implements 'FromJSON' can be used
72−-- here, this is quite a powerful way to parse JSON. See the
73−-- documentation in 'FromJSON' for how to implement this class for
74−-- your own data types.
76−-- The downside is that you have to write the parser yourself, the
77−-- upside is that you have complete control over the way the JSON is
80−-- /DECODING CUSTOM DATA TYPES GENERICALLY WITH TYPEABLE/
82−-- If you don't want such control and would prefer the JSON be parsed
83−-- to your own data types automatically according to some reasonably
84−-- sensible isomorphic implementation, you can use the generic parser
85−-- based on 'Data.Typeable.Typeable' and 'Data.Data.Data'. Switch to
86−-- the 'Data.Aeson.Generic' module, and you can do the following:
88−-- > λ> decode "[1]" :: Maybe [Int]
90−-- > λ> :m + Data.Typeable Data.Data
91−-- > λ> :set -XDeriveDataTypeable
92−-- > λ> data Person = Person { personName :: String, personAge :: Int } deriving (Data,Typeable,Show)
93−-- > λ> encode Person { personName = "Chris", personAge = 123 }
94−-- > "{\"personAge\":123,\"personName\":\"Chris\"}"
95−-- > λ> decode "{\"personAge\":123,\"personName\":\"Chris\"}" :: Maybe Person
97−-- > personName = "Chris", personAge = 123
100−-- Be aware that the encoding might not be what you expect:
102−-- > λ> data Foo = Foo Int Int deriving (Data,Typeable,Show)
103−-- > λ> encode (Foo 1 2)
106−-- So it's better to treat the 'Data.Aeson.Generic.decode' and
107−-- 'Data.Aeson.Generic.encode' functions as an isomorphism, but do not
108−-- rely or care about the actual intermediate representation.
112−-- Note that the JSON standard only allows arrays or objects of things
113−-- at the top-level, so calling decode on a simple type will not work:
115−-- > λ> decode "1" :: Maybe Int
117−-- > λ> decode "1" :: Maybe String
120−-- So stick to objects (e.g. maps in Haskell) or arrays (lists in Haskell):
122−-- > λ> decode "[1,2,3]" :: Maybe [Int]
125−-- Likewise, for encoding to JSON you can encode anything that's an
126−-- instance of 'ToJSON', which does include simple types. So beware
127−-- that this aspect of the API is not isomorphic:
129−-- > λ> encode [1,2,3]
131−-- > λ> decode (encode [1]) :: Maybe [Int]
135−-- > λ> decode (encode (1 :: Int)) :: Maybe Int
138−-- Alternatively see 'Data.Aeson.Parser.value' to parse non-toplevel
141module Data.Aeson
15module Data.Aeson
20+ -- * Working directly with the JSON AST
143 -- * Encoding and decoding
26 -- * Encoding and decoding
27+ -- $encoding-and-decoding
145 , decode'
29 , decode'
146 , eitherDecode
30 , eitherDecode
@@ -208,3 +92,115 @@ eitherDecode = eitherDecodeWith json fromJSON
208eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
92eitherDecode' :: (FromJSON a) => L.ByteString -> Either String a
209eitherDecode' = eitherDecodeWith json' fromJSON
93eitherDecode' = eitherDecodeWith json' fromJSON
210{-# INLINE eitherDecode' #-}
94{-# INLINE eitherDecode' #-}
98+-- The most common way to use the library is to define a data type,
99+-- corresponding to some JSON data you want to work with, and then
100+-- write either a 'FromJSON' instance, a to 'ToJSON' instance, or both
101+-- for that type. For example, given this JSON data:
103+-- > { "name": "Joe", "age": 12 }
105+-- we create a matching data type:
107+-- > data Person = Person
112+-- To decode data, we need to define a 'FromJSON' instance:
114+-- > {-# LANGUAGE OverloadedStrings #-}
116+-- > instance FromJSON Coord where
117+-- > parseJSON (Object v) = Person <$>
120+-- > -- A non-Object value is of the wrong type, so fail.
121+-- > parseJSON _ = mzero
123+-- We can now parse the JSON data like so:
125+-- > >>> decode "{\"name\":\"Joe\",\"age\":12}" :: Maybe Person
126+-- > Just (Person {name = "Joe", age = 12})
128+-- The explicit type signature can often be omitted as the compiler
129+-- can deduce the type using type inference.
131+-- To encode data, we need to define a 'ToJSON' instance:
133+-- > instance ToJSON Person where
134+-- > toJSON (Person name age) = object ["name" .= name, "age" .= age]
136+-- We can now encode a value like so:
138+-- > >>> encode (Person {name = "Joe", age = 12})
139+-- > "{\"name\":\"Joe\",\"age\":12}"
141+-- There are predefined 'FromJSON' and 'ToJSON' instances for many
142+-- types. Here's an example using lists and 'Int's:
144+-- > >>> decode "[1,2,3]" :: Maybe [Int]
147+-- And here's an example using the 'Data.Map.Map' type to get a map of
150+-- > >>> decode "{\"foo\":1,\"bar\":2}" :: Maybe (Map String Int)
151+-- > Just (fromList [("bar",2),("foo",1)])
153+-- See the documentation of 'FromJSON' and 'ToJSON' for some examples
154+-- how you can automatically dervice instances in some circumstances.
159+-- Sometimes you want to work with JSON data directly, without first
160+-- converting it to a custom data type. This can be useful if you want
161+-- to e.g. convert JSON data to YAML data, without knowing what the
162+-- contents of the original JSON data was. The 'Value' type, which is
163+-- an instance of 'FromJSON', is used to represent an arbitrary JSON
164+-- AST. Example usage:
166+-- > >>> decode "{\"foo\": 123}" :: Maybe Value
167+-- > Just (Object (fromList [("foo",Number 123)]))
168+-- > >>> decode "{\"foo\": [\"abc\",\"def\"]}" :: Maybe Value
169+-- > Just (Object (fromList [("foo",Array (fromList [String "abc",String "def"]))]))
171+-- Once you have a 'Value' you can write recursive functions to
172+-- traverse it and make arbitrary transformations.
176+-- Note that the JSON standard only allows arrays or objects of things
177+-- at the top-level, so calling decode on a simple type will not work:
179+-- > >>> decode "1" :: Maybe Int
181+-- > >>> decode "1" :: Maybe String
184+-- Likewise, for encoding to JSON you can encode anything that's an
185+-- instance of 'ToJSON', which does include simple types. So beware
186+-- that this aspect of the API is not isomorphic:
188+-- > >>> encode [1,2,3]
190+-- > >>> decode (encode [1]) :: Maybe [Int]
194+-- > >>> decode (encode (1 :: Int)) :: Maybe Int
197+-- Alternatively see 'Data.Aeson.Parser.value' to parse non-toplevel
200+-- $encoding-and-decoding
202+-- Encoding and decoding is a two step process. To encode a value, it
203+-- is first converted to a generic representation, using 'ToJSON'. The
204+-- generic representation is then encoded as JSON data. To decode a
205+-- value the process is reversed and 'FromJSON' is used instead. Both
206+-- these steps are combined in the 'encode' and 'decode' functions.