on master help sign in
Add a TH example.
4666c3bBryan O'Sullivan
examples/Demo.hsdeleted−70
@@ -1,70 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−
3−-- Simplest example of parsing and encoding JSON with Aeson.
4−
5−-- Above, we enable OverloadedStrings to allow a literal string (e.g. "name")
6−-- to be automatically converted to Data.Text.
7−-- This is useful when using Aeson's functions such as (.:) which expect Text.
8−-- Without it we'd need to use pack.
9−
10−import Data.Aeson
11−import qualified Data.Aeson.Types as T
12−
13−import Data.Attoparsec (parse, Result(..))
14−import Data.Text (Text)
15−import Control.Applicative ((<$>))
16−import Control.Monad (mzero)
17−import qualified Data.ByteString.Char8 as BS
18−-- Aeson's "encode" to JSON generates lazy bytestrings
19−import qualified Data.ByteString.Lazy.Char8 as BSL
20−
21−-- In main we'll parse a JSON message into a Msg and display that,
22−-- then we'll encode a different Msg as JSON, and display it.
23−main ::IO ()
24−main = do
25− print $ parseMsgFromString exampleJSONMessage
26− let reply = Msg "hello Aeson!"
27− putStrLn $ "Encoded reply: " ++ BSL.unpack (encode reply)
28−
29−-- this is the type we'll be converting to and from JSON
30−data Msg = Msg Text deriving (Show)
31−
32−-- here's how we should parse JSON and construct a Msg
33−instance FromJSON Msg where
34− parseJSON (Object v) = Msg <$> v .: "message"
35− parseJSON _ = mzero
36−
37−-- here's how we should encode a Msg as JSON
38−instance ToJSON Msg where
39− toJSON (Msg s) = object [ "message" .= s]
40−
41−-- Here's one way to actually run the parsers.
42−--
43−-- Note that we do two parses:
44−-- once into JSON then one more into our final type.
45−-- There are a number of choices when dealing with parse failures.
46−-- Here we've chosen to parse to Maybe Msg, and a Nothing will be returned
47−-- if parseJSON fails. (More informative options are available.)
48−--
49−-- This should take us (depending on success or failure)
50−-- from {"message": "hello world"} to Just (Msg "hello world")
51−-- or to Nothing
52−--
53−-- Note also that we have not checked here that the input has been completely
54−-- consumed, so:
55−-- {"message": "hello world"} foo BIG mistake
56−-- would yield the same successfully translated message!
57−-- We could look in "rest" for the remainder.
58−parseMsgFromString :: String -> Maybe Msg
59−parseMsgFromString s =
60− let bs = BS.pack s
61− in case parse json bs of
62− (Done rest r) -> T.parseMaybe parseJSON r :: Maybe Msg
63− _ -> Nothing
64−
65−-- Here's the example JSON message we're going to try to parse:
66−-- {"message": "hello world"}
67−-- It's a JSON object with a single pair, having key 'message', and a string value.
68−-- It could have more fields and structure, but that's all we're going to parse out of it.
69−exampleJSONMessage :: String
70−exampleJSONMessage = "{\"message\":\"hello world\"}"
examples/Generic.hs+1−1
@@ -30,7 +30,7 @@ data Coord = Coord { x :: Double, y :: Double }
30instance FromJSON Coord
30instance FromJSON Coord
31instance ToJSON Coord
31instance ToJSON Coord
32
32
33−main ::IO ()
33+main :: IO ()
34main = do
34main = do
35 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
35 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
36 print req
36 print req
examples/GenericSYB.hs+1−1
@@ -22,7 +22,7 @@ import qualified Data.ByteString.Lazy.Char8 as BL
22data Coord = Coord { x :: Double, y :: Double }
22data Coord = Coord { x :: Double, y :: Double }
23 deriving (Show, Typeable, Data)
23 deriving (Show, Typeable, Data)
24
24
25−main ::IO ()
25+main :: IO ()
26main = do
26main = do
27 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
27 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
28 print req
28 print req
examples/Simplest.hs+1−1
@@ -22,7 +22,7 @@ instance FromJSON Coord where
22 v .: "y"
22 v .: "y"
23 parseJSON _ = empty
23 parseJSON _ = empty
24
24
25−main ::IO ()
25+main :: IO ()
26main = do
26main = do
27 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
27 let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
28 print req
28 print req
examples/TemplateHaskell.hsnew file+29
@@ -0,0 +1,29 @@
1+-- We can use Template Haskell (TH) to generate instances of the
2+-- FromJSON and ToJSON classes automatically. This is the fastest way
3+-- to add JSON support for a type.
4+
5+{-# LANGUAGE TemplateHaskell #-}
6+
7+{-# LANGUAGE OverloadedStrings #-}
8+
9+import Data.Aeson (decode, encode)
10+import Data.Aeson.TH (deriveJSON)
11+import qualified Data.ByteString.Lazy.Char8 as BL
12+
13+data Coord = Coord { x :: Double, y :: Double }
14+ deriving (Show)
15+
16+-- This splice will derive instances of ToJSON and FromJSON for us.
17+--
18+-- The use of "id" below is a placeholder function to transform the
19+-- names of the type's fields. We don't want to transform them, so we
20+-- use the identity function.
21+
22+$(deriveJSON id ''Coord)
23+
24+main :: IO ()
25+main = do
26+ let req = decode "{\"x\":3.0,\"y\":-1.0}" :: Maybe Coord
27+ print req
28+ let reply = Coord 123.4 20
29+ BL.putStrLn (encode reply)
release-notes.markdown+32−9
@@ -1,27 +1,50 @@
1# 0.3 to 0.4
1# 0.3 to 0.4
2
2
3+## Ease of use
4+
5+The new [`decode`
6+function](http://hackage.haskell.org/packages/archive/aeson/latest/doc/html/Data-Aeson.html#v:decode)
7+complements the longstanding `encode` function, and makes the API
8+simpler.
9+
10+[New examples](https://github.com/bos/aeson/tree/master/examples) make
11+it easier to learn to use the package.
12+
13+
3## Generics support
14## Generics support
4
15
5−Aeson's support for data-type generic programming makes it possible to
16+aeson's support for data-type generic programming makes it possible to
6use JSON encodings of most data types without writing any boilerplate
17use JSON encodings of most data types without writing any boilerplate
7instances.
18instances.
8
19
9Thanks to Bas Van Dijk, aeson now supports the two major schemes for
20Thanks to Bas Van Dijk, aeson now supports the two major schemes for
10doing datatype-generic programming:
21doing datatype-generic programming:
11
22
12−* the newer mechanism, [built into GHC
23+* the modern mechanism, [built into GHC
13 itself](http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html)
24 itself](http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-programming.html)
14
25
15−* the older mechanism, based on SYB (for "scrap your boilerplate")
26+* the older mechanism, based on SYB (aka "scrap your boilerplate")
16
27
17−The GHC-based generics are fast and terse: in fact, they're generally
28+The modern GHC-based generic mechanism is fast and terse: in fact, its
18−comparable in performance to hand-written `ToJSON` and `FromJSON`
29+performance is generally comparable in performance to hand-written and
19−instances. To see how to use GHC generics, see
30+TH-derived `ToJSON` and `FromJSON` instances. To see how to use GHC
31+generics, refer to
20[`examples/Generic.hs`](https://github.com/bos/aeson/blob/master/examples/Generic.hs).
32[`examples/Generic.hs`](https://github.com/bos/aeson/blob/master/examples/Generic.hs).
21
33
22The SYB-based generics support lives in
34The SYB-based generics support lives in
23−[Data.Aeson.Generic](http://hackage.haskell.org/packages/archive/aeson/0.4.0.0/doc/html/Data-Aeson-Generic.html),
35+[Data.Aeson.Generic](http://hackage.haskell.org/packages/archive/aeson/latest/doc/html/Data-Aeson-Generic.html),
24−and is provided mainly for users of GHC older than 7.2. It's far
36+and is provided mainly for users of GHC older than 7.2. SYB is far
25slower (by about 10x) than the more modern generic mechanism. To see
37slower (by about 10x) than the more modern generic mechanism. To see
26−how to use SYB generics, see
38+how to use SYB generics, refer to
27[`examples/GenericSYB.hs`](https://github.com/bos/aeson/blob/master/examples/GenericSYB.hs).
39[`examples/GenericSYB.hs`](https://github.com/bos/aeson/blob/master/examples/GenericSYB.hs).
40+
41+
42+## Improved performance
43+
44+* We switched the intermediate representation of JSON objects from
45+ `Data.Map` to
46+ [`Data.HashMap`](http://hackage.haskell.org/package/unordered-containers),
47+ which has improved type conversion performance.
48+
49+* Instances of `ToJSON` and `FromJSON` for tuples are between 45% and
50+ 70% faster than in 0.3.