on master help sign in
Switch numerics to use the Number type

This is very nearly as fast as Doubles for parsing, and more accurate for dealing with integers.

commit6b40e5dfc27063257a5c3121b606c01e0279d9cf authorBryan O'Sullivan <bos@serpentine.com> dateWed 16 Feb 2011, 00:14 (16 years ago) parent592fcb1
3 files changed+41−28
Data/Aeson/Generic.hs+3 Data/Aeson/Parser.hs+1−1 Data/Aeson/Types.hs+37−27
Data/Aeson/Generic.hs+3
@@ -24,6 +24,7 @@ import Control.Arrow (first)
2424import Control.Monad.State.Strict
2525import Data.Aeson.Functions (transformMap)
2626import Data.Aeson.Types hiding (FromJSON(..), ToJSON(..), fromJSON)
27+import Data.Attoparsec.Number (Number)
2728import Data.Generics
2829import Data.Int (Int8, Int16, Int32, Int64)
2930import Data.IntSet (IntSet)
@@ -62,6 +63,7 @@ toJSON = toJSON_generic
6263 `extQ` (T.toJSON :: T Word32)
6364 `extQ` (T.toJSON :: T Word64)
6465 `extQ` (T.toJSON :: T Double)
66+ `extQ` (T.toJSON :: T Number)
6567 `extQ` (T.toJSON :: T Float)
6668 `extQ` (T.toJSON :: T Rational)
6769 `extQ` (T.toJSON :: T Char)
@@ -149,6 +151,7 @@ parseJSON j = parseJSON_generic j
149151 `extR` (value :: F Word32)
150152 `extR` (value :: F Word64)
151153 `extR` (value :: F Double)
154+ `extR` (value :: F Number)
152155 `extR` (value :: F Float)
153156 `extR` (value :: F Rational)
154157 `extR` (value :: F Char)
Data/Aeson/Parser.hs+1−1
@@ -63,7 +63,7 @@ array_ = {-# SCC "array_" #-} do
6363-- | Parse any JSON value. Use 'json' in preference to this function
6464-- if you are parsing data from an untrusted source.
6565value :: Parser Value
66−value = most <|> (Number <$> double)
66+value = most <|> (Number <$> number)
6767 where
6868 most = do
6969 c <- anyChar
Data/Aeson/Types.hs+37−27
@@ -49,6 +49,7 @@ import Data.Text (Text, pack, unpack)
4949import Data.Text.Encoding (decodeUtf8, encodeUtf8)
5050import Data.Time.Clock (UTCTime)
5151import Data.Time.Format (FormatTime, formatTime, parseTime)
52+import Data.Attoparsec.Char8 (Number(..))
5253import Data.Typeable (Typeable)
5354import Data.Vector (Vector)
5455import Data.Word (Word, Word8, Word16, Word32, Word64)
@@ -136,7 +137,7 @@ type Array = Vector Value
136137data Value = Object Object
137138 | Array Array
138139 | String Text
139− | Number Double
140+ | Number Number
140141 | Bool !Bool
141142 | Null
142143 deriving (Eq, Show, Typeable, Data)
@@ -145,7 +146,7 @@ instance NFData Value where
145146 rnf (Object o) = rnf o
146147 rnf (Array a) = V.foldl' (\x y -> rnf y `seq` x) () a
147148 rnf (String s) = rnf s
148− rnf (Number n) = rnf n
149+ rnf (Number n) = case n of I i -> rnf i; D d -> rnf d
149150 rnf (Bool b) = rnf b
150151 rnf Null = ()
151152
@@ -298,10 +299,21 @@ instance FromJSON Char where
298299 {-# INLINE parseJSON #-}
299300
300301instance ToJSON Double where
301− toJSON = Number
302+ toJSON = Number . D
302303 {-# INLINE toJSON #-}
303304
304305instance FromJSON Double where
306+ parseJSON (Number n) = case n of
307+ D d -> pure d
308+ I i -> pure (fromIntegral i)
309+ parseJSON _ = empty
310+ {-# INLINE parseJSON #-}
311+
312+instance ToJSON Number where
313+ toJSON = Number
314+ {-# INLINE toJSON #-}
315+
316+instance FromJSON Number where
305317 parseJSON (Number n) = pure n
306318 parseJSON _ = empty
307319 {-# INLINE parseJSON #-}
@@ -311,7 +323,9 @@ instance ToJSON Float where
311323 {-# INLINE toJSON #-}
312324
313325instance FromJSON Float where
314− parseJSON (Number n) = pure . fromRational . toRational $ n
326+ parseJSON (Number n) = case n of
327+ D d -> pure . fromRational . toRational $ d
328+ I i -> pure (fromIntegral i)
315329 parseJSON _ = empty
316330 {-# INLINE parseJSON #-}
317331
@@ -320,7 +334,9 @@ instance ToJSON (Ratio Integer) where
320334 {-# INLINE toJSON #-}
321335
322336instance FromJSON (Ratio Integer) where
323− parseJSON (Number n) = pure . toRational $ n
337+ parseJSON (Number n) = case n of
338+ D d -> pure . toRational $ d
339+ I i -> pure (fromIntegral i)
324340 parseJSON _ = empty
325341 {-# INLINE parseJSON #-}
326342
@@ -329,17 +345,20 @@ instance ToJSON Int where
329345 {-# INLINE toJSON #-}
330346
331347instance FromJSON Int where
332− parseJSON (Number n) = pure (floor n)
333− parseJSON _ = empty
348+ parseJSON = parseIntegral
334349 {-# INLINE parseJSON #-}
335350
351+parseIntegral :: Integral a => Value -> Parser a
352+parseIntegral (Number n) = pure (floor n)
353+parseIntegral _ = empty
354+{-# INLINE parseIntegral #-}
355+
336356instance ToJSON Integer where
337357 toJSON = Number . fromIntegral
338358 {-# INLINE toJSON #-}
339359
340360instance FromJSON Integer where
341− parseJSON (Number n) = pure (floor n)
342− parseJSON _ = empty
361+ parseJSON = parseIntegral
343362 {-# INLINE parseJSON #-}
344363
345364instance ToJSON Int8 where
@@ -347,8 +366,7 @@ instance ToJSON Int8 where
347366 {-# INLINE toJSON #-}
348367
349368instance FromJSON Int8 where
350− parseJSON (Number n) = pure (floor n)
351− parseJSON _ = empty
369+ parseJSON = parseIntegral
352370 {-# INLINE parseJSON #-}
353371
354372instance ToJSON Int16 where
@@ -356,8 +374,7 @@ instance ToJSON Int16 where
356374 {-# INLINE toJSON #-}
357375
358376instance FromJSON Int16 where
359− parseJSON (Number n) = pure (floor n)
360− parseJSON _ = empty
377+ parseJSON = parseIntegral
361378 {-# INLINE parseJSON #-}
362379
363380instance ToJSON Int32 where
@@ -365,8 +382,7 @@ instance ToJSON Int32 where
365382 {-# INLINE toJSON #-}
366383
367384instance FromJSON Int32 where
368− parseJSON (Number n) = pure (floor n)
369− parseJSON _ = empty
385+ parseJSON = parseIntegral
370386 {-# INLINE parseJSON #-}
371387
372388instance ToJSON Int64 where
@@ -374,8 +390,7 @@ instance ToJSON Int64 where
374390 {-# INLINE toJSON #-}
375391
376392instance FromJSON Int64 where
377− parseJSON (Number n) = pure (floor n)
378− parseJSON _ = empty
393+ parseJSON = parseIntegral
379394 {-# INLINE parseJSON #-}
380395
381396instance ToJSON Word where
@@ -383,8 +398,7 @@ instance ToJSON Word where
383398 {-# INLINE toJSON #-}
384399
385400instance FromJSON Word where
386− parseJSON (Number n) = pure (floor n)
387− parseJSON _ = empty
401+ parseJSON = parseIntegral
388402 {-# INLINE parseJSON #-}
389403
390404instance ToJSON Word8 where
@@ -392,8 +406,7 @@ instance ToJSON Word8 where
392406 {-# INLINE toJSON #-}
393407
394408instance FromJSON Word8 where
395− parseJSON (Number n) = pure (floor n)
396− parseJSON _ = empty
409+ parseJSON = parseIntegral
397410 {-# INLINE parseJSON #-}
398411
399412instance ToJSON Word16 where
@@ -401,8 +414,7 @@ instance ToJSON Word16 where
401414 {-# INLINE toJSON #-}
402415
403416instance FromJSON Word16 where
404− parseJSON (Number n) = pure (floor n)
405− parseJSON _ = empty
417+ parseJSON = parseIntegral
406418 {-# INLINE parseJSON #-}
407419
408420instance ToJSON Word32 where
@@ -410,8 +422,7 @@ instance ToJSON Word32 where
410422 {-# INLINE toJSON #-}
411423
412424instance FromJSON Word32 where
413− parseJSON (Number n) = pure (floor n)
414− parseJSON _ = empty
425+ parseJSON = parseIntegral
415426 {-# INLINE parseJSON #-}
416427
417428instance ToJSON Word64 where
@@ -419,8 +430,7 @@ instance ToJSON Word64 where
419430 {-# INLINE toJSON #-}
420431
421432instance FromJSON Word64 where
422− parseJSON (Number n) = pure (floor n)
423− parseJSON _ = empty
433+ parseJSON = parseIntegral
424434 {-# INLINE parseJSON #-}
425435
426436instance ToJSON Text where