-- |
-- Module : Data.Text.Internal.Read
-- Copyright : (c) 2014 Bryan O'Sullivan
--
-- License : BSD-style
-- Maintainer : bos@serpentine.com
-- Stability : experimental
-- Portability : GHC
--
-- Common internal functiopns for reading textual data.
module Data.Text.Internal.Read ( IReader , IParser(..) , T(..) , digitToInt , hexDigitToInt , perhaps ) where import Control.Applicative (
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
{
runP
::
IReader
t
a
} instance
Functor
(
IParser
t
) where
fmap
f
m
=
P
$
fmap
(
first
f
)
.
runP
m
instance
Applicative
(
IParser
t
) where
pure
a
=
P
$
\
t
->
Right
(
a
,
t
)
{-# INLINE
pure
#-}
(<*>)
=
ap
instance
Monad
(
IParser
t
) where
return
=
pure
m
>>=
k
=
P
$
\
t
-> case
runP
m
t
of
Left
err
->
Left
err
Right
(
a
,
t'
) ->
runP
(
k
a
)
t'
{-# INLINE (>>=) #-}
fail
msg
=
P
$
\_ ->
Left
msg
data
T
=
T
!
Integer
!
Int
perhaps
::
a
->
IParser
t
a
->
IParser
t
a
perhaps
def
m
=
P
$
\
t
-> case
runP
m
t
of
Left
_ ->
Right
(
def
,
t
)
r
@(
Right
_) ->
r
hexDigitToInt
::
Char
->
Int
hexDigitToInt
c
|
c
>=
'0'
&&
c
<=
'9'
=
ord
c
-
ord
'0'
|
c
>=
'a'
&&
c
<=
'f'
=
ord
c
-
(
ord
'a'
-
10
) |
otherwise
=
ord
c
-
(
ord
'A'
-
10
)
digitToInt
::
Char
->
Int
digitToInt
c
=
ord
c
-
ord
'0'