on master help sign in
Merge pull request #41 from basvandijk/hashmap

Use HashMap instead of Map for Objects

commit2b64dbfce85513b93488e7cd28a6f3ad3b67cb6f authorBryan O'Sullivan <bos@serpentine.com> dateThu 17 Nov 2011, 11:52 (15 years ago) parent07365acf8605f4
8 files changed+102−109
Data/Aeson/Encode.hs+2−2 Data/Aeson/Functions.hs+26−22 Data/Aeson/Generic.hs+26−25 Data/Aeson/Parser.hs+2−2 Data/Aeson/TH.hs+10−10 Data/Aeson/Types/Class.hs+24−25 Data/Aeson/Types/Generic.hs+4−4 Data/Aeson/Types/Internal.hs+8−19
Data/Aeson/Encode.hs+2−2
@@ -25,7 +25,7 @@ import Data.Monoid (mappend)
2525import Numeric (showHex)
2626import Blaze.Text (double, integral)
2727import qualified Data.ByteString.Lazy.Char8 as L
28−import qualified Data.Map as M
28+import qualified Data.HashMap.Strict as H
2929import qualified Data.Text as T
3030import qualified Data.Vector as V
3131
@@ -42,7 +42,7 @@ fromValue (Array v)
4242 V.foldr f (fromChar ']') (V.unsafeTail v)
4343 where f a z = fromChar ',' `mappend` fromValue a `mappend` z
4444fromValue (Object m) =
45− case M.toList m of
45+ case H.toList m of
4646 (x:xs) -> fromChar '{' `mappend`
4747 one x `mappend`
4848 foldr f (fromChar '}') xs
Data/Aeson/Functions.hs+26−22
@@ -1,15 +1,14 @@
11module Data.Aeson.Functions
2− (
3− hashMap
4− , mapHash
5− , transformMap
2+ ( mapHashKeyVal
3+ , hashMapKey
4+ , mapKeyVal
5+ , mapKey
66 -- * String conversions
77 , decode
88 , strict
99 , lazy
1010 ) where
1111
12−import Control.Arrow ((***), first)
1312import Data.Hashable (Hashable)
1413import Data.Text (Text)
1514import Data.Text.Encoding (decodeUtf8, encodeUtf8)
@@ -18,23 +17,28 @@ import qualified Data.ByteString.Lazy as L
1817import qualified Data.HashMap.Strict as H
1918import qualified Data.Map as M
2019
21−-- | Transform one map into another. The ordering of keys must be
22−-- preserved by the key transformation function.
23−transformMap :: (Ord k2) => (k1 -> k2) -> (v1 -> v2)
24− -> M.Map k1 v1 -> M.Map k2 v2
25−transformMap fk fv = M.fromAscList . map (fk *** fv) . M.toAscList
26−{-# INLINE transformMap #-}
27−
28−-- | Transform a 'H.HashMap' into a 'M.Map'.
29−hashMap :: (Ord k2) => (k1 -> k2) -> (v1 -> v2)
30− -> H.HashMap k1 v1 -> M.Map k2 v2
31−hashMap fk kv = M.fromList . map (fk *** kv) . H.toList
32−{-# INLINE hashMap #-}
33−
34−-- | Transform a 'M.Map' into a 'H.HashMap'.
35−mapHash :: (Eq k2, Hashable k2) => (k1 -> k2) -> M.Map k1 v -> H.HashMap k2 v
36−mapHash fk = H.fromList . map (first fk) . M.toList
37−{-# INLINE mapHash #-}
20+-- | Transform a 'M.Map' into a 'H.HashMap' while transforming the keys.
21+mapHashKeyVal :: (Eq k2, Hashable k2) => (k1 -> k2) -> (v1 -> v2)
22+ -> M.Map k1 v1 -> H.HashMap k2 v2
23+mapHashKeyVal fk kv = M.foldrWithKey (\k v -> H.insert (fk k) (kv v)) H.empty
24+{-# INLINE mapHashKeyVal #-}
25+
26+-- | Transform a 'M.Map' into a 'H.HashMap' while transforming the keys.
27+hashMapKey :: (Ord k2) => (k1 -> k2)
28+ -> H.HashMap k1 v -> M.Map k2 v
29+hashMapKey kv = H.foldrWithKey (M.insert . kv) M.empty
30+{-# INLINE hashMapKey #-}
31+
32+-- | Transform the keys and values of a 'H.HashMap'.
33+mapKeyVal :: (Eq k2, Hashable k2) => (k1 -> k2) -> (v1 -> v2)
34+ -> H.HashMap k1 v1 -> H.HashMap k2 v2
35+mapKeyVal fk kv = H.foldrWithKey (\k v -> H.insert (fk k) (kv v)) H.empty
36+{-# INLINE mapKeyVal #-}
37+
38+-- | Transform the keys of a 'H.HashMap'.
39+mapKey :: (Eq k2, Hashable k2) => (k1 -> k2) -> H.HashMap k1 v -> H.HashMap k2 v
40+mapKey fk = mapKeyVal fk id
41+{-# INLINE mapKey #-}
3842
3943strict :: L.ByteString -> Text
4044strict = decode . B.concat . L.toChunks
Data/Aeson/Generic.hs+26−25
@@ -98,7 +98,7 @@ toJSON = toJSON_generic
9898 | otherwise = modError "toJSON" $
9999 "cannot convert map keyed by type " ++ show tyrep
100100 where tyrep = typeOf . head . Map.keys $ m
101− remap f = Object . transformMap (f . fromJust . cast) toJSON $ m
101+ remap f = Object . mapHashKeyVal (f . fromJust . cast) toJSON $ m
102102
103103 hashMapAny m
104104 | tyrep == typeOf DT.empty = remap id
@@ -109,7 +109,7 @@ toJSON = toJSON_generic
109109 | otherwise = modError "toJSON" $
110110 "cannot convert map keyed by type " ++ show tyrep
111111 where tyrep = typeOf . head . H.keys $ m
112− remap f = Object . hashMap (f . fromJust . cast) toJSON $ m
112+ remap f = Object . mapKeyVal (f . fromJust . cast) toJSON $ m
113113
114114
115115-- Skip leading '_' in field name so we can use keywords
@@ -202,40 +202,41 @@ parseJSON j = parseJSON_generic j
202202 vector = case j of
203203 Array js -> V.mapM parseJSON js
204204 _ -> myFail
205+
205206 mapAny :: forall e f. (Data e, Data f) => Parser (Map.Map f e)
206207 mapAny
207− | tyrep `elem` stringyTypes = res
208+ | tyrep == typeOf DT.empty = process id
209+ | tyrep == typeOf LT.empty = process LT.fromStrict
210+ | tyrep == typeOf "" = process DT.unpack
211+ | tyrep == typeOf B.empty = process encodeUtf8
212+ | tyrep == typeOf L.empty = process lazy
208213 | otherwise = myFail
209− where res = case j of
210− Object js -> Map.mapKeysMonotonic trans <$> T.mapM parseJSON js
211− _ -> myFail
212− trans
213− | tyrep == typeOf DT.empty = remap id
214− | tyrep == typeOf LT.empty = remap LT.fromStrict
215− | tyrep == typeOf "" = remap DT.unpack
216− | tyrep == typeOf B.empty = remap encodeUtf8
217− | tyrep == typeOf L.empty = remap lazy
218− | otherwise = modError "parseJSON"
219− "mapAny -- should never happen"
220− tyrep = typeOf (undefined :: f)
221− remap f = fromJust . cast . f
214+ where
215+ process f = maybe myFail return . cast =<< parseWith f
216+ parseWith :: (Ord c) => (Text -> c) -> Parser (Map.Map c e)
217+ parseWith f = case j of
218+ Object js -> Map.fromList . map (first f) . H.toList <$>
219+ T.mapM parseJSON js
220+ _ -> myFail
221+ tyrep = typeOf (undefined :: f)
222+
222223 hashMapAny :: forall e f. (Data e, Data f) => Parser (H.HashMap f e)
223224 hashMapAny
224− | tyrep == typeOf "" = process DT.unpack
225− | tyrep == typeOf LT.empty = process LT.fromStrict
226225 | tyrep == typeOf DT.empty = process id
226+ | tyrep == typeOf LT.empty = process LT.fromStrict
227+ | tyrep == typeOf "" = process DT.unpack
228+ | tyrep == typeOf B.empty = process encodeUtf8
229+ | tyrep == typeOf L.empty = process lazy
227230 | otherwise = myFail
228231 where
229232 process f = maybe myFail return . cast =<< parseWith f
230233 parseWith :: (Eq c, Hashable c) => (Text -> c) -> Parser (H.HashMap c e)
231234 parseWith f = case j of
232− Object js -> H.fromList . map (first f) . Map.toList <$>
233− T.mapM parseJSON js
234− _ -> myFail
235+ Object js -> mapKey f <$> T.mapM parseJSON js
236+ _ -> myFail
235237 tyrep = typeOf (undefined :: f)
238+
236239 myFail = modFail "parseJSON" $ "bad data: " ++ show j
237− stringyTypes = [typeOf LT.empty, typeOf DT.empty, typeOf B.empty,
238− typeOf L.empty, typeOf ""]
239240
240241parseJSON_generic :: (Data a) => Value -> Parser a
241242parseJSON_generic j = generic
@@ -274,7 +275,7 @@ parseJSON_generic j = generic
274275 go _ c _ jd = modFail "parseJSON" $
275276 "bad decodeArgs data " ++ show (c, jd)
276277
277− fromJSObject = map (first unpack) . Map.toList
278+ fromJSObject = map (first unpack) . H.toList
278279
279280 -- Build the value by stepping through the list of subparts.
280281 construct c = evalStateT $ fromConstrM f c
@@ -287,7 +288,7 @@ parseJSON_generic j = generic
287288 -- Select the named fields from a JSON object.
288289 selectFields fjs = mapM sel
289290 where sel f = maybe (modFail "parseJSON" $ "field does not exist " ++
290− f) return $ Map.lookup (mungeField f) fjs
291+ f) return $ H.lookup (mungeField f) fjs
291292
292293 -- Count how many arguments a constructor has. The value x is
293294 -- used to determine what type the constructor returns.
Data/Aeson/Parser.hs+2−2
@@ -27,7 +27,6 @@ import Data.Attoparsec.Char8
2727import Data.Bits ((.|.), shiftL)
2828import Data.ByteString as B
2929import Data.Char (chr)
30−import Data.Map as Map
3130import Data.Monoid (mappend, mempty)
3231import Data.Text as T
3332import Data.Text.Encoding (decodeUtf8)
@@ -37,6 +36,7 @@ import qualified Data.Attoparsec as A
3736import qualified Data.Attoparsec.Zepto as Z
3837import qualified Data.ByteString.Char8 as B8
3938import qualified Data.ByteString.Unsafe as B
39+import qualified Data.HashMap.Strict as H
4040
4141-- | Parse a top-level JSON value. This must be either an object or
4242-- an array.
@@ -55,7 +55,7 @@ object_ = {-# SCC "object_" #-} do
5555 b <- char ':' *> skipSpace *> value
5656 return (a,b)
5757 vals <- ((pair <* skipSpace) `sepBy` (char ',' *> skipSpace)) <* char '}'
58− return . Object $ Map.fromList vals
58+ return . Object $ H.fromList vals
5959
6060array_ :: Parser Value
6161array_ = {-# SCC "array_" #-} do
Data/Aeson/TH.hs+10−10
@@ -38,8 +38,8 @@ import Control.Applicative
3838import Control.Monad
3939import Data.Aeson
4040import Data.Aeson.TH
41−import qualified Data.Map as M
42−import qualified Data.Text as T
41+import qualified Data.HashMap.Strict as H
42+import qualified Data.Text as T
4343import qualified Data.Vector as V
4444
4545instance 'ToJSON' a => 'ToJSON' (D a) where
@@ -72,7 +72,7 @@ instance 'FromJSON' a => 'FromJSON' (D a) where
7272 \value ->
7373 case value of
7474 'Object' obj ->
75− case M.toList obj of
75+ case H.toList obj of
7676 [(conKey, conVal)] ->
7777 case conKey of
7878 _ | conKey == T.pack \"Nullary\" ->
@@ -97,7 +97,7 @@ instance 'FromJSON' a => 'FromJSON' (D a) where
9797 | conKey == T.pack \"Record\" ->
9898 case conVal of
9999 'Object' recObj ->
100− if M.size recObj == 3
100+ if H.size recObj == 3
101101 then Record \<$\> recObj '.:' T.pack \"One\"
102102 \<*\> recObj '.:' T.pack \"Two\"
103103 \<*\> recObj '.:' T.pack \"Three\"
@@ -171,8 +171,8 @@ import Text.Show ( show )
171171import Control.Monad ( (>>=) )
172172import Prelude ( fromInteger )
173173#endif
174−-- from containers:
175−import qualified Data.Map as M ( lookup, toList, size )
174+-- from unordered-containers:
175+import qualified Data.HashMap.Strict as H ( lookup, toList, size )
176176-- from template-haskell:
177177import Language.Haskell.TH
178178-- from text:
@@ -465,7 +465,7 @@ consFromJSON tName withField cons = do
465465 let -- Convert the Data.Map inside the Object to a list and pattern match
466466 -- against it. It must contain a single element otherwise the parse will
467467 -- fail.
468− caseLst = caseE ([e|M.toList|] `appE` varE obj)
468+ caseLst = caseE ([e|H.toList|] `appE` varE obj)
469469 [ match (listP [tupP [varP conKey, varP conVal]])
470470 (normalB caseKey)
471471 []
@@ -563,7 +563,7 @@ parseArgs tName withField (RecC conName ts) =
563563 | (field, _, _) <- ts
564564 ]
565565 match (conP 'Object [varP obj])
566− ( normalB $ condE ( infixApp ([|M.size|] `appE` varE obj)
566+ ( normalB $ condE ( infixApp ([|H.size|] `appE` varE obj)
567567 [|(==)|]
568568 (litE $ integerL $ genericLength ts)
569569 )
@@ -576,7 +576,7 @@ parseArgs tName withField (RecC conName ts) =
576576 ++ show (length ts)
577577 ++ " name/value pairs"
578578 )
579− ( infixApp ([|show . M.size|] `appE` varE obj)
579+ ( infixApp ([|show . H.size|] `appE` varE obj)
580580 [|(++)|]
581581 (litE $ stringL $ " name/value pairs")
582582 )
@@ -656,7 +656,7 @@ parseTypeMismatch tName conName expected actual =
656656
657657lookupField :: (FromJSON a) => String -> String -> Object -> T.Text -> Parser a
658658lookupField tName rec obj key =
659− case M.lookup key obj of
659+ case H.lookup key obj of
660660 Nothing -> unknownFieldFail tName rec (T.unpack key)
661661 Just v -> parseJSON v
662662
Data/Aeson/Types/Class.hs+24−25
@@ -49,6 +49,7 @@ import Data.Text (Text, pack, unpack)
4949import Data.Text.Encoding (encodeUtf8)
5050import Data.Time.Clock (UTCTime)
5151import Data.Time.Format (FormatTime, formatTime, parseTime)
52+import Data.Traversable (traverse)
5253import Data.Typeable (Typeable)
5354import Data.Vector (Vector)
5455import Data.Word (Word, Word8, Word16, Word32, Word64)
@@ -208,7 +209,7 @@ instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
208209 {-# INLINE toJSON #-}
209210
210211instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
211− parseJSON (Object (M.toList -> [(key, value)]))
212+ parseJSON (Object (H.toList -> [(key, value)]))
212213 | key == left = Left <$> parseJSON value
213214 | key == right = Right <$> parseJSON value
214215 parseJSON _ = fail ""
@@ -507,70 +508,68 @@ instance FromJSON a => FromJSON (IntMap.IntMap a) where
507508 {-# INLINE parseJSON #-}
508509
509510instance (ToJSON v) => ToJSON (M.Map Text v) where
510− toJSON = Object . M.map toJSON
511+ toJSON = Object . M.foldrWithKey (\k -> H.insert k . toJSON) H.empty
511512 {-# INLINE toJSON #-}
512513
513514instance (FromJSON v) => FromJSON (M.Map Text v) where
514− parseJSON (Object o) = M.fromAscList <$> mapM go (M.toAscList o)
515− where go (k,v) = ((,) k) <$> parseJSON v
515+ parseJSON (Object o) = H.foldrWithKey M.insert M.empty <$> traverse parseJSON o
516516 parseJSON v = typeMismatch "Map Text a" v
517517
518518instance (ToJSON v) => ToJSON (M.Map LT.Text v) where
519− toJSON = Object . transformMap LT.toStrict toJSON
519+ toJSON = Object . mapHashKeyVal LT.toStrict toJSON
520520
521521instance (FromJSON v) => FromJSON (M.Map LT.Text v) where
522− parseJSON = fmap (M.mapKeysMonotonic LT.fromStrict) . parseJSON
522+ parseJSON = fmap (hashMapKey LT.fromStrict) . parseJSON
523523
524524instance (ToJSON v) => ToJSON (M.Map String v) where
525− toJSON = Object . transformMap pack toJSON
525+ toJSON = Object . mapHashKeyVal pack toJSON
526526
527527instance (FromJSON v) => FromJSON (M.Map String v) where
528− parseJSON = fmap (M.mapKeysMonotonic unpack) . parseJSON
528+ parseJSON = fmap (hashMapKey unpack) . parseJSON
529529
530530instance (ToJSON v) => ToJSON (M.Map B.ByteString v) where
531− toJSON = Object . transformMap decode toJSON
531+ toJSON = Object . mapHashKeyVal decode toJSON
532532
533533instance (FromJSON v) => FromJSON (M.Map B.ByteString v) where
534− parseJSON = fmap (M.mapKeysMonotonic encodeUtf8) . parseJSON
534+ parseJSON = fmap (hashMapKey encodeUtf8) . parseJSON
535535
536536instance (ToJSON v) => ToJSON (M.Map LB.ByteString v) where
537− toJSON = Object . transformMap strict toJSON
537+ toJSON = Object . mapHashKeyVal strict toJSON
538538
539539instance (FromJSON v) => FromJSON (M.Map LB.ByteString v) where
540− parseJSON = fmap (M.mapKeysMonotonic lazy) . parseJSON
540+ parseJSON = fmap (hashMapKey lazy) . parseJSON
541541
542542instance (ToJSON v) => ToJSON (H.HashMap Text v) where
543− toJSON = Object . hashMap id toJSON
543+ toJSON = Object . H.map toJSON
544544 {-# INLINE toJSON #-}
545545
546546instance (FromJSON v) => FromJSON (H.HashMap Text v) where
547− parseJSON (Object o) = H.fromList <$> mapM go (M.toList o)
548− where go (k,v) = ((,) k) <$> parseJSON v
547+ parseJSON (Object o) = traverse parseJSON o
549548 parseJSON v = typeMismatch "HashMap Text a" v
550549
551550instance (ToJSON v) => ToJSON (H.HashMap LT.Text v) where
552− toJSON = Object . M.fromList . H.foldrWithKey (\k v -> ((LT.toStrict k,toJSON v) :)) []
551+ toJSON = Object . mapKeyVal LT.toStrict toJSON
553552
554553instance (FromJSON v) => FromJSON (H.HashMap LT.Text v) where
555− parseJSON = fmap (mapHash LT.fromStrict) . parseJSON
554+ parseJSON = fmap (mapKey LT.fromStrict) . parseJSON
556555
557556instance (ToJSON v) => ToJSON (H.HashMap String v) where
558− toJSON = Object . hashMap pack toJSON
557+ toJSON = Object . mapKeyVal pack toJSON
559558
560559instance (FromJSON v) => FromJSON (H.HashMap String v) where
561− parseJSON = fmap (mapHash unpack) . parseJSON
560+ parseJSON = fmap (mapKey unpack) . parseJSON
562561
563562instance (ToJSON v) => ToJSON (H.HashMap B.ByteString v) where
564− toJSON = Object . hashMap decode toJSON
563+ toJSON = Object . mapKeyVal decode toJSON
565564
566565instance (FromJSON v) => FromJSON (H.HashMap B.ByteString v) where
567− parseJSON = fmap (mapHash encodeUtf8) . parseJSON
566+ parseJSON = fmap (mapKey encodeUtf8) . parseJSON
568567
569568instance (ToJSON v) => ToJSON (H.HashMap LB.ByteString v) where
570− toJSON = Object . hashMap strict toJSON
569+ toJSON = Object . mapKeyVal strict toJSON
571570
572571instance (FromJSON v) => FromJSON (H.HashMap LB.ByteString v) where
573− parseJSON = fmap (mapHash lazy) . parseJSON
572+ parseJSON = fmap (mapKey lazy) . parseJSON
574573
575574instance ToJSON Value where
576575 toJSON a = a
@@ -689,7 +688,7 @@ fromJSON = parse parseJSON
689688-- in an object for it to be valid. If the key and value are
690689-- optional, use '(.:?)' instead.
691690(.:) :: (FromJSON a) => Object -> Text -> Parser a
692−obj .: key = case M.lookup key obj of
691+obj .: key = case H.lookup key obj of
693692 Nothing -> fail $ "key " ++ show key ++ " not present"
694693 Just v -> parseJSON v
695694{-# INLINE (.:) #-}
@@ -702,7 +701,7 @@ obj .: key = case M.lookup key obj of
702701-- from an object without affecting its validity. If the key and
703702-- value are mandatory, use '(.:)' instead.
704703(.:?) :: (FromJSON a) => Object -> Text -> Parser (Maybe a)
705−obj .:? key = case M.lookup key obj of
704+obj .:? key = case H.lookup key obj of
706705 Nothing -> pure Nothing
707706 Just v -> parseJSON v
708707{-# INLINE (.:?) #-}
Data/Aeson/Types/Generic.hs+4−4
@@ -31,7 +31,7 @@ import Data.Aeson.Types.Class
3131import Data.Aeson.Types.Internal
3232import Data.Text (pack, unpack)
3333import GHC.Generics
34−import qualified Data.Map as M
34+import qualified Data.HashMap.Strict as H
3535import qualified Data.Text as T
3636import qualified Data.Vector as V
3737
@@ -119,7 +119,7 @@ instance (GObject a, GObject b) => GObject (a :+: b) where
119119 {-# INLINE gObject #-}
120120
121121instance (Constructor c, GToJSON a, ConsToJSON a) => GObject (C1 c a) where
122− gObject = M.singleton (pack $ conName (undefined :: t c a p)) . gToJSON
122+ gObject = H.singleton (pack $ conName (undefined :: t c a p)) . gToJSON
123123 {-# INLINE gObject #-}
124124
125125--------------------------------------------------------------------------------
@@ -159,7 +159,7 @@ instance ( GFromProduct a, GFromProduct b
159159 {-# INLINE gParseJSON #-}
160160
161161instance (GFromSum a, GFromSum b) => GFromJSON (a :+: b) where
162− gParseJSON (Object (M.toList -> [keyVal@(key, _)])) =
162+ gParseJSON (Object (H.toList -> [keyVal@(key, _)])) =
163163 case gParseSum keyVal of
164164 Nothing -> notFound $ unpack key
165165 Just p -> p
@@ -200,7 +200,7 @@ instance (GFromRecord a, GFromRecord b) => GFromRecord (a :*: b) where
200200 {-# INLINE gParseRecord #-}
201201
202202instance (Selector s, GFromJSON a) => GFromRecord (S1 s a) where
203− gParseRecord = maybe (notFound key) gParseJSON . M.lookup (T.pack key)
203+ gParseRecord = maybe (notFound key) gParseJSON . H.lookup (T.pack key)
204204 where
205205 key = selName (undefined :: t s a p)
206206 {-# INLINE gParseRecord #-}
Data/Aeson/Types/Internal.hs+8−19
@@ -33,16 +33,14 @@ import Control.Applicative
3333import Control.DeepSeq (NFData(..))
3434import Control.Monad.State.Strict
3535import Data.Attoparsec.Char8 (Number(..))
36−import Data.Data (Data)
3736import Data.Hashable (Hashable(..))
38−import Data.List (foldl')
39−import Data.Map (Map)
37+import Data.HashMap.Strict (HashMap)
4038import Data.Monoid (Monoid(..))
4139import Data.String (IsString(..))
4240import Data.Text (Text, pack)
4341import Data.Typeable (Typeable)
4442import Data.Vector (Vector)
45−import qualified Data.Map as M
43+import qualified Data.HashMap.Strict as H
4644import qualified Data.Vector as V
4745
4846-- | The result of running a 'Parser'.
@@ -151,7 +149,7 @@ apP d e = do
151149{-# INLINE apP #-}
152150
153151-- | A JSON \"object\" (key\/value map).
154−type Object = Map Text Value
152+type Object = HashMap Text Value
155153
156154-- | A JSON \"array\" (sequence).
157155type Array = Vector Value
@@ -163,31 +161,22 @@ data Value = Object !Object
163161 | Number !Number
164162 | Bool !Bool
165163 | Null
166− deriving (Eq, Show, Typeable, Data)
164+ deriving (Eq, Show, Typeable)
167165
168166instance NFData Value where
169− rnf (Object o) = obj_rnf o
167+ rnf (Object o) = rnf o
170168 rnf (Array a) = V.foldl' (\x y -> rnf y `seq` x) () a
171169 rnf (String s) = rnf s
172170 rnf (Number n) = case n of I i -> rnf i; D d -> rnf d
173171 rnf (Bool b) = rnf b
174172 rnf Null = ()
175173
176−obj_rnf :: (NFData k, NFData v) => Map k v -> ()
177−#if MIN_VERSION_containers(0,4,2)
178−obj_rnf = rnf
179−#elif MIN_VERSION_containers(0,4,1)
180−obj_rnf = M.foldlWithKey' (\_ k v -> rnf k `seq` rnf v) ()
181−#else
182−obj_rnf = rnf . M.toList
183−#endif
184−
185174instance IsString Value where
186175 fromString = String . pack
187176 {-# INLINE fromString #-}
188177
189178instance Hashable Value where
190− hash (Object o) = foldl' hashWithSalt 0 . M.toList $ o
179+ hash (Object o) = H.foldl' hashWithSalt 0 o
191180 hash (Array a) = V.foldl' hashWithSalt 1 a
192181 hash (String s) = 2 `hashWithSalt` s
193182 hash (Number n) = 3 `hashWithSalt` case n of I i -> hash i; D d -> hash d
@@ -206,7 +195,7 @@ isEmptyArray _ = False
206195
207196-- | The empty object.
208197emptyObject :: Value
209−emptyObject = Object M.empty
198+emptyObject = Object H.empty
210199
211200-- | Run a 'Parser'.
212201parse :: (a -> Parser b) -> a -> Result b
@@ -229,5 +218,5 @@ type Pair = (Text, Value)
229218-- | Create a 'Value' from a list of name\/value 'Pair's. If duplicate
230219-- keys arise, earlier keys and their associated values win.
231220object :: [Pair] -> Value
232−object = Object . M.fromList
221+object = Object . H.fromList
233222{-# INLINE object #-}