@@ -551,6 +551,9 @@ number = scientifically $ \s ->
551551scientific :: Parser Scientific
552552scientific = scientifically id
553553
554+-- A strict pair
555+data SP = SP !Integer {-# UNPACK #-}!Int
556+
554557{-# INLINE scientifically #-}
555558scientifically :: (Scientific -> a) -> Parser a
556559scientifically h = do
@@ -563,21 +566,21 @@ scientifically h = do
563566
564567 n <- decimal
565568
566− let f fracDigits = Sci.scientific (B8.foldl' step n fracDigits)
567− (negate $ B8.length fracDigits)
569+ let f fracDigits = SP (B8.foldl' step n fracDigits)
570+ (negate $ B8.length fracDigits)
568571 step a w = a * 10 + fromIntegral (w - 48)
569572
570573 dotty <- I.peekWord8
571574 -- '.' -> ascii 46
572− s <- case dotty of
573− Just 46 -> I.anyWord8 *> (f <$> I.takeWhile isDigit_w8)
574− _ -> pure (Sci.scientific n 0)
575+ SP c e <- case dotty of
576+ Just 46 -> I.anyWord8 *> (f <$> I.takeWhile isDigit_w8)
577+ _ -> pure (SP n 0)
575578
576− let !signedCoeff | positive = coefficient s
577− | otherwise = negate $ coefficient s
579+ let !signedCoeff | positive = c
580+ | otherwise = -c
578581
579582 let littleE = 101
580583 bigE = 69
581− (I.satisfy (\c -> c == littleE || c == bigE) *>
582− fmap (h . Sci.scientific signedCoeff . (base10Exponent s +)) (signed decimal)) <|>
583− return (h $ Sci.scientific signedCoeff (base10Exponent s))
584+ (I.satisfy (\ex -> ex == littleE || ex == bigE) *>
585+ fmap (h . Sci.scientific signedCoeff . (e +)) (signed decimal)) <|>
586+ return (h $ Sci.scientific signedCoeff e)