@@ -51,6 +51,9 @@ module Streamly.Internal.Unicode.Parser
5151 , double
5252 , decimal
5353 , hexadecimal
54+
55+ -- * Utilities
56+ , mkDouble
5457 )
5558where
5659
@@ -404,6 +407,19 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
404407 extract (SPAfterExponent mult num decimalPlaces powerMult powerNum) =
405408 Done 0 $ exitSPAfterExponent mult num decimalPlaces powerMult powerNum
406409
410+-- XXX We can have a `realFloat` parser instead to parse any RealFloat value.
411+-- And a integral parser to read any integral value.
412+
413+-- | @mkDouble mantissa exponent@ converts a mantissa and exponent to a
414+-- 'Double' value equivalent to @mantissa * 10^exponent@. It does not check for
415+-- overflow, powers more than 308 will overflow.
416+{-# INLINE mkDouble #-}
417+mkDouble :: Integer -> Int -> Double
418+mkDouble mantissa power =
419+ if power > 0
420+ then fromRational (fromIntegral (mantissa * 10 ^ power))
421+ else fromRational (mantissa % 10 ^ (-power))
422+
407423-- | Parse a decimal 'Double' value. This parser accepts an optional sign (+ or
408424-- -) followed by at least one decimal digit. Decimal digits are optionally
409425-- followed by a decimal point and at least one decimal digit after the point.
@@ -414,6 +430,13 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
414430--
415431-- >>> import qualified Streamly.Data.Stream as Stream
416432-- >>> import qualified Streamly.Unicode.Parser as Unicode
433+-- >>> import qualified Streamly.Internal.Unicode.Parser as Unicode (number, mkDouble)
434+--
435+-- Definition:
436+--
437+-- >>> double = uncurry Unicode.mkDouble <$> Unicode.number
438+--
439+-- Examples:
417440--
418441-- >>> p = Stream.parse Unicode.double . Stream.fromList
419442--
@@ -450,11 +473,4 @@ number = Parser (\s a -> return $ step s a) initial (return . extract)
450473--
451474{-# INLINE double #-}
452475double :: Monad m => Parser Char m Double
453−double = fmap f number
454−
455− where
456−
457− f (m, e) =
458− if e > 0
459− then fromIntegral (m * 10 ^ e)
460− else fromRational (m % 10 ^ (-e))
476+double = uncurry mkDouble <$> number