, longMonthName
, longMonthNameP
- , show2
, show4
+ , show2
+ , show2'
- , read2
, read4
+ , read2
+ , read2'
, show4digitsTZ
, read4digitsTZ
import Data.Ascii (AsciiBuilder)
import qualified Data.Ascii as A
import Data.Attoparsec.Char8 as P
+import Data.Char
import Data.Monoid.Unicode
import Data.Fixed
import Data.Time
| i ≥ 0 ∧ i < 100 = BT.integral i
| otherwise = error ("show2: the integer i must satisfy 0 <= i < 100: " ⧺ show i)
+show2' ∷ Integral i ⇒ i → AsciiBuilder
+{-# INLINE show2' #-}
+show2' = A.unsafeFromBuilder ∘ go
+ where
+ go i | i ≥ 0 ∧ i < 10 = B.fromByteString " " ⊕ BT.digit i
+ | i ≥ 0 ∧ i < 100 = BT.integral i
+ | otherwise = error ("show2': the integer i must satisfy 0 <= i < 100: " ⧺ show i)
+
read4 ∷ Num n ⇒ Parser n
{-# INLINEABLE read4 #-}
read4 = do n1 ← digit'
n2 ← digit'
return (n1 * 10 + n2)
-digit' ∷ Num n ⇒ Parser n
-digit' = fromC <$> P.digit
+read2' ∷ Num n ⇒ Parser n
+{-# INLINEABLE read2' #-}
+read2' = do n1 ← (char ' ' *> pure 0) <|> digit'
+ n2 ← digit'
+ return (n1 * 10 + n2)
-fromC ∷ Num n ⇒ Char → n
-fromC '0' = 0
-fromC '1' = 1
-fromC '2' = 2
-fromC '3' = 3
-fromC '4' = 4
-fromC '5' = 5
-fromC '6' = 6
-fromC '7' = 7
-fromC '8' = 8
-fromC '9' = 9
-fromC _ = undefined
+digit' ∷ Num n ⇒ Parser n
+{-# INLINE digit' #-}
+digit' = fromIntegral <$> fromC <$> P.digit
+ where
+ {-# INLINE fromC #-}
+ fromC c = ord c - ord '0'
show4digitsTZ ∷ TimeZone → AsciiBuilder
show4digitsTZ tz