@@ -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