bytestring-read-0.3.0: src/Data/ByteString/Read/Integral.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
module Data.ByteString.Read.Integral
( integral'
, integral
, int
) where
import Data.Proxy.Compat
import GHC.TypeLits.Compat
import Data.ByteString.Read.Class as C
-- $setup
-- >>> :set -XDataKinds -XOverloadedStrings
-- >>> import qualified Data.ByteString as S
-- >>> import qualified Data.ByteString.Lazy as L
integral_ :: (Radix b, Num n, Source s) => proxy b -> s -> (n, Int, s)
integral_ pn = loop 0 0
where
loop !i !d !s
| C.null s = (i, d, s)
| not (isDigit pn (C.head s)) = (i, d, s)
| otherwise = loop
(i * fromIntegral (natVal pn) + (fromIntegral $ unsafeToDigit pn (C.head s)))
(d+1) (C.tail s)
{-# INLINABLE integral_ #-}
-- | convert bytestring into unsigned integral using radix
--
-- >>> integral' (Proxy :: Proxy 10) "12345" :: Maybe (Int, S.ByteString)
-- Just (12345,"")
-- >>> integral' (Proxy :: Proxy 2) "10112" :: Maybe (Int, L.ByteString)
-- Just (11,"2")
-- >>> integral' (Proxy :: Proxy 36) "Z" :: Maybe (Double, S.ByteString)
-- Just (35.0,"")
integral' :: (Radix b, Num n, Source s) => proxy b -> s -> Maybe (n, s)
integral' pn s0 = case integral_ pn s0 of
(_, 0, _) -> Nothing
(n, _, s) -> Just (n, s)
{-# INLINABLE integral' #-}
-- | @
-- integral = 'integral'' (Proxy :: Proxy 10)
-- @
integral :: (Num n, Source s) => s -> Maybe (n, s)
integral = integral' (Proxy :: Proxy 10)
{-# INLINABLE integral #-}
-- | @
-- int = integral
-- @
int :: Source s => s -> Maybe (Int, s)
int = integral
{-# INLINABLE int #-}