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
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9' = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0'
| Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'f' = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Char -> Int
ord Char
'a' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10)
| Bool
otherwise = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Char -> Int
ord Char
'A' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
10)
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'