on cb720fe help sign in
62 lines 1.6 kB history raw
1-- |
2-- Module : Data.Text.Internal.Read
3-- Copyright : (c) 2014 Bryan O'Sullivan
4--
5-- License : BSD-style
6-- Maintainer : bos@serpentine.com
7-- Stability : experimental
8-- Portability : GHC
9--
10-- Common internal functiopns for reading textual data.
11module Data.Text.Internal.Read
12 (
13 IReader
14 , IParser(..)
15 , T(..)
16 , digitToInt
17 , hexDigitToInt
18 , perhaps
19 ) where
21import Control.Applicative (Applicative(..))
22import Control.Arrow (first)
23import Control.Monad (ap)
24import Data.Char (ord)
26type IReader t a = t -> Either String (a,t)
28newtype IParser t a = P {
29 runP :: IReader t a
30 }
32instance Functor (IParser t) where
33 fmap f m = P $ fmap (first f) . runP m
35instance Applicative (IParser t) where
36 pure a = P $ \t -> Right (a,t)
37 {-# INLINE pure #-}
38 (<*>) = ap
40instance Monad (IParser t) where
41 return = pure
42 m >>= k = P $ \t -> case runP m t of
43 Left err -> Left err
44 Right (a,t') -> runP (k a) t'
45 {-# INLINE (>>=) #-}
46 fail msg = P $ \_ -> Left msg
48data T = T !Integer !Int
50perhaps :: a -> IParser t a -> IParser t a
51perhaps def m = P $ \t -> case runP m t of
52 Left _ -> Right (def,t)
53 r@(Right _) -> r
55hexDigitToInt :: Char -> Int
56hexDigitToInt c
57 | c >= '0' && c <= '9' = ord c - ord '0'
58 | c >= 'a' && c <= 'f' = ord c - (ord 'a' - 10)
59 | otherwise = ord c - (ord 'A' - 10)
61digitToInt :: Char -> Int
62digitToInt c = ord c - ord '0'