@@ -124,8 +124,8 @@ module Data.Attoparsec.Text
124124import Control.Applicative (pure, (<$>), (*>), (<*), (<|>))
125125import Data.Attoparsec.Combinator
126126import Data.Attoparsec.Number (Number(..))
127−import Data.Scientific (Scientific, coefficient, base10Exponent)
128−import qualified Data.Scientific as Sci (scientific)
127+import Data.Scientific (Scientific)
128+import qualified Data.Scientific as Sci
129129import Data.Attoparsec.Text.Internal (Parser, Result, parse, takeWhile1)
130130import Data.Bits (Bits, (.|.), shiftL)
131131import Data.Char (isAlpha, isDigit, isSpace, ord)
@@ -373,7 +373,7 @@ rational = scientifically realToFrac
373373-- This function does not accept string representations of \"NaN\" or
374374-- \"Infinity\".
375375double :: Parser Double
376−double = rational
376+double = scientifically Sci.toRealFloat
377377
378378-- | Parse a number, attempting to preserve both speed and precision.
379379--
@@ -388,11 +388,11 @@ double = rational
388388-- \"Infinity\".
389389number :: Parser Number
390390number = scientifically $ \s ->
391− let e = base10Exponent s
392− c = coefficient s
391+ let e = Sci.base10Exponent s
392+ c = Sci.coefficient s
393393 in if e >= 0
394394 then I (c * 10 ^ e)
395− else D (fromInteger c / 10 ^ negate e)
395+ else D (Sci.toRealFloat s)
396396
397397-- | Parse a scientific number.
398398--
@@ -400,6 +400,9 @@ number = scientifically $ \s ->
400400scientific :: Parser Scientific
401401scientific = scientifically id
402402
403+-- A strict pair
404+data SP = SP !Integer {-# UNPACK #-}!Int
405+
403406{-# INLINE scientifically #-}
404407scientifically :: (Scientific -> a) -> Parser a
405408scientifically h = do
@@ -408,19 +411,19 @@ scientifically h = do
408411
409412 n <- decimal
410413
411− let f fracDigits = Sci.scientific (T.foldl' step n fracDigits)
412− (negate $ T.length fracDigits)
414+ let f fracDigits = SP (T.foldl' step n fracDigits)
415+ (negate $ T.length fracDigits)
413416 step a c = a * 10 + fromIntegral (ord c - 48)
414417
415− s <- (I.satisfy (=='.') *> (f <$> I.takeWhile isDigit)) <|>
416− pure (Sci.scientific n 0)
418+ SP c e <- (I.satisfy (=='.') *> (f <$> I.takeWhile isDigit)) <|>
419+ pure (SP n 0)
417420
418− let !signedCoeff | positive = coefficient s
419− | otherwise = negate $ coefficient s
421+ let !signedCoeff | positive = c
422+ | otherwise = -c
420423
421− (I.satisfy (\c -> c == 'e' || c == 'E') *>
422− fmap (h . Sci.scientific signedCoeff . (base10Exponent s +)) (signed decimal)) <|>
423− return (h $ Sci.scientific signedCoeff (base10Exponent s))
424+ (I.satisfy (\w -> w == 'e' || w == 'E') *>
425+ fmap (h . Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
426+ return (h $ Sci.scientific signedCoeff e)
424427
425428-- | Parse a single digit, as recognised by 'isDigit'.
426429digit :: Parser Char