module Data.Text.Internal.Read
(
IReader
, IParser(..)
, T(..)
, digitToInt
, hexDigitToInt
, perhaps
) where
import Control.Applicative as App (Applicative(..))
import Control.Arrow (first)
import Control.Monad (ap)
import Data.Char (ord)
type IReader t a = t -> Either String (a,t)
newtype IParser t a = P {
IParser t a -> IReader t a
runP :: IReader t a
}
instance Functor (IParser t) where
fmap :: (a -> b) -> IParser t a -> IParser t b
fmap a -> b
f IParser t a
m = IReader t b -> IParser t b
forall t a. IReader t a -> IParser t a
P (IReader t b -> IParser t b) -> IReader t b -> IParser t b
forall a b. (a -> b) -> a -> b
$ ((a, t) -> (b, t)) -> Either String (a, t) -> Either String (b, t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (a, t) -> (b, t)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first a -> b
f) (Either String (a, t) -> Either String (b, t))
-> (t -> Either String (a, t)) -> IReader t b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IParser t a -> t -> Either String (a, t)
forall t a. IParser t a -> IReader t a
runP IParser t a
m
instance Applicative (IParser t) where
pure :: a -> IParser t a
pure a
a = IReader t a -> IParser t a
forall t a. IReader t a -> IParser t a
P (IReader t a -> IParser t a) -> IReader t a -> IParser t a
forall a b. (a -> b) -> a -> b
$ \t
t -> (a, t) -> Either String (a, t)
forall a b. b -> Either a b
Right (a
a,t
t)
{-# INLINE pure #-}
<*> :: IParser t (a -> b) -> IParser t a -> IParser t b
(<*>) = IParser t (a -> b) -> IParser t a -> IParser t b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad (IParser t) where
return :: a -> IParser t a
return = a -> IParser t a
forall (f :: * -> *) a. Applicative f => a -> f a
App.pure
IParser t a
m >>= :: IParser t a -> (a -> IParser t b) -> IParser t b
>>= a -> IParser t b
k = IReader t b -> IParser t b
forall t a. IReader t a -> IParser t a
P (IReader t b -> IParser t b) -> IReader t b -> IParser t b
forall a b. (a -> b) -> a -> b
$ \t
t -> case IParser t a -> IReader t a
forall t a. IParser t a -> IReader t a
runP IParser t a
m t
t of
Left String
err -> String -> Either String (b, t)
forall a b. a -> Either a b
Left String
err
Right (a
a,t
t') -> IParser t b -> IReader t b
forall t a. IParser t a -> IReader t a
runP (a -> IParser t b
k a
a) t
t'
{-# INLINE (>>=) #-}
data T = T !Integer !Int
perhaps :: a -> IParser t a -> IParser t a
perhaps :: a -> IParser t a -> IParser t a
perhaps a
def IParser t a
m = IReader t a -> IParser t a
forall t a. IReader t a -> IParser t a
P (IReader t a -> IParser t a) -> IReader t a -> IParser t a
forall a b. (a -> b) -> a -> b
$ \t
t -> case IParser t a -> IReader t a
forall t a. IParser t a -> IReader t a
runP IParser t a
m t
t of
Left String
_ -> (a, t) -> Either String (a, t)
forall a b. b -> Either a b
Right (a
def,t
t)
r :: Either String (a, t)
r@(Right (a, t)
_) -> Either String (a, t)
r
hexDigitToInt :: Char -> Int
hexDigitToInt :: Char -> Int
hexDigitToInt Char
c
| Word
to0 Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
10 = Word -> Int
wordToInt Word
to0
| Word
toa Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
6 = Word -> Int
wordToInt Word
toa Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10
| Bool
otherwise = Word -> Int
wordToInt Word
toA Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10
where
ordW :: Word
ordW = Int -> Word
intToWord (Char -> Int
ord Char
c)
to0 :: Word
to0 = Word
ordW Word -> Word -> Word
forall a. Num a => a -> a -> a
- Int -> Word
intToWord (Char -> Int
ord Char
'0')
toa :: Word
toa = Word
ordW Word -> Word -> Word
forall a. Num a => a -> a -> a
- Int -> Word
intToWord (Char -> Int
ord Char
'a')
toA :: Word
toA = Word
ordW Word -> Word -> Word
forall a. Num a => a -> a -> a
- Int -> Word
intToWord (Char -> Int
ord Char
'A')
digitToInt :: Char -> Int
digitToInt :: Char -> Int
digitToInt Char
c = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0'
intToWord :: Int -> Word
intToWord :: Int -> Word
intToWord = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral
wordToInt :: Word -> Int
wordToInt :: Word -> Int
wordToInt = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral