{-# LANGUAGE BangPatterns, FlexibleContexts, ScopedTypeVariables #-}
module Text.ProtocolBuffers.TextMessage (
messagePutText,
messageGetText,
TextMsg(..),
TextType(..),
tellShow,
tellSubMessage,
getRead,
getSubMessage,
) where
import Control.Monad.Identity (Identity)
import Control.Monad (void)
import Control.Monad.Writer (Writer, execWriter, tell, censor)
import Data.Char
import Data.Foldable (toList)
import Data.Int
import Data.List (intercalate)
import Data.Sequence (singleton)
import Data.Traversable
import Data.Word
import Text.Parsec
import Text.Printf
import Text.ProtocolBuffers.Basic
import Text.Read
import qualified Data.ByteString.Lazy.Char8 as C8
import qualified Data.ByteString.Lazy.UTF8 as U8
import qualified Text.Parsec.Token as T
type Log = Seq (Int, String)
type Output = Writer Log ()
class TextMsg a where
textPut :: a -> Output
textGet :: Stream s Identity Char => Parsec s () a
class TextType a where
tellT :: String -> a -> Output
getT :: Stream s Identity Char => String -> Parsec s () a
tells :: String -> Output
tells :: String -> Output
tells String
s = Seq (Int, String) -> Output
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Seq (Int, String) -> Output) -> Seq (Int, String) -> Output
forall a b. (a -> b) -> a -> b
$ (Int, String) -> Seq (Int, String)
forall a. a -> Seq a
singleton (Int
0, String
s)
tellShow :: Show a => String -> a -> Output
tellShow :: String -> a -> Output
tellShow String
name a
v = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v
tellStr :: String -> ByteString -> Output
tellStr :: String -> ByteString -> Output
tellStr String
name ByteString
s = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
dumpDecimal ByteString
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""
tellSubMessage :: TextMsg a => String -> a -> Output
tellSubMessage :: String -> a -> Output
tellSubMessage String
name a
m = do
String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" {"
Output -> Output
forall a.
WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
indent (Output -> Output) -> Output -> Output
forall a b. (a -> b) -> a -> b
$ a -> Output
forall a. TextMsg a => a -> Output
textPut a
m
String -> Output
tells String
"}"
where
indent :: WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
indent = (Seq (Int, String) -> Seq (Int, String))
-> WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
forall w (m :: * -> *) a. MonadWriter w m => (w -> w) -> m a -> m a
censor (((Int, String) -> (Int, String))
-> Seq (Int, String) -> Seq (Int, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(!Int
n, String
s) -> (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, String
s)))
dumpDecimal :: ByteString -> String
dumpDecimal :: ByteString -> String
dumpDecimal = (Char -> String -> String) -> String -> ByteString -> String
forall a. (Char -> a -> a) -> a -> ByteString -> a
C8.foldr Char -> String -> String
escape []
where
escape :: Char -> String -> String
escape Char
'\n' String
str = String
"\\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
escape Char
'\"' String
str = String
"\\\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
escape Char
c String
str | Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& Char -> Bool
isPrint Char
c = Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
str
escape Char
c String
str = String -> Char -> String
forall r. PrintfType r => String -> r
printf String
"\\%03d" Char
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
instance TextType Int32 where
tellT :: String -> Int32 -> Output
tellT = String -> Int32 -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Int32
getT = Parsec s () Int32 -> String -> Parsec s () Int32
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Int32
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
integer
instance TextType Int64 where
tellT :: String -> Int64 -> Output
tellT = String -> Int64 -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Int64
getT = Parsec s () Int64 -> String -> Parsec s () Int64
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Int64
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
integer
instance TextType Word32 where
tellT :: String -> Word32 -> Output
tellT = String -> Word32 -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Word32
getT = Parsec s () Word32 -> String -> Parsec s () Word32
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Word32
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
natural
instance TextType Word64 where
tellT :: String -> Word64 -> Output
tellT = String -> Word64 -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Word64
getT = Parsec s () Word64 -> String -> Parsec s () Word64
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Word64
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
natural
instance TextType Bool where
tellT :: String -> Bool -> Output
tellT String
name Bool
True = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": true"
tellT String
name Bool
False = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": false"
getT :: String -> Parsec s () Bool
getT String
name = do
String
v <- Parsec s () String -> String -> Parsec s () String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar (String -> Parsec s () String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"true" Parsec s () String -> Parsec s () String -> Parsec s () String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> Parsec s () String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"false") String
name
Bool -> Parsec s () Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"true")
instance TextType Double where
tellT :: String -> Double -> Output
tellT = String -> Double -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Double
getT = Parsec s () Double -> String -> Parsec s () Double
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Double
forall s. Stream s Identity Char => Parsec s () Double
float
instance TextType Float where
tellT :: String -> Float -> Output
tellT = String -> Float -> Output
forall a. Show a => String -> a -> Output
tellShow
getT :: String -> Parsec s () Float
getT String
name = Double -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> Float)
-> ParsecT s () Identity Double -> Parsec s () Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity Double
-> String -> ParsecT s () Identity Double
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity Double
forall s. Stream s Identity Char => Parsec s () Double
float String
name
instance TextType Utf8 where
tellT :: String -> Utf8 -> Output
tellT String
name (Utf8 ByteString
s) = String -> ByteString -> Output
tellStr String
name ByteString
s
getT :: String -> Parsec s () Utf8
getT String
name = String -> Utf8
uFromString (String -> Utf8)
-> ParsecT s () Identity String -> Parsec s () Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity String
-> String -> ParsecT s () Identity String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity String
forall s. Stream s Identity Char => Parsec s () String
stringLiteral String
name
instance TextType ByteString where
tellT :: String -> ByteString -> Output
tellT = String -> ByteString -> Output
tellStr
getT :: String -> Parsec s () ByteString
getT String
name = String -> ByteString
U8.fromString (String -> ByteString)
-> ParsecT s () Identity String -> Parsec s () ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity String
-> String -> ParsecT s () Identity String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity String
forall s. Stream s Identity Char => Parsec s () String
stringLiteral String
name
instance TextType a => TextType (Maybe a) where
tellT :: String -> Maybe a -> Output
tellT String
_ Maybe a
Nothing = () -> Output
forall (m :: * -> *) a. Monad m => a -> m a
return ()
tellT String
name (Just a
v) = String -> a -> Output
forall a. TextType a => String -> a -> Output
tellT String
name a
v
getT :: String -> Parsec s () (Maybe a)
getT String
name = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> ParsecT s () Identity a -> Parsec s () (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT s () Identity a
forall a s.
(TextType a, Stream s Identity Char) =>
String -> Parsec s () a
getT String
name
instance TextType a => TextType (Seq a) where
tellT :: String -> Seq a -> Output
tellT String
name Seq a
xs = WriterT (Seq (Int, String)) Identity (Seq ()) -> Output
forall (f :: * -> *) a. Functor f => f a -> f ()
void (WriterT (Seq (Int, String)) Identity (Seq ()) -> Output)
-> WriterT (Seq (Int, String)) Identity (Seq ()) -> Output
forall a b. (a -> b) -> a -> b
$ Seq a
-> (a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ())
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM Seq a
xs ((a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ()))
-> (a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ())
forall a b. (a -> b) -> a -> b
$ String -> a -> Output
forall a. TextType a => String -> a -> Output
tellT String
name
getT :: String -> Parsec s () (Seq a)
getT = String -> String -> Parsec s () (Seq a)
forall a. HasCallStack => String -> a
error String
"should not take sequence directly"
messagePutText :: TextMsg a => a -> String
messagePutText :: a -> String
messagePutText = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> (a -> [String]) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq String -> [String]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Seq String -> [String]) -> (a -> Seq String) -> a -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, String) -> String) -> Seq (Int, String) -> Seq String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, String) -> String
setIndent (Seq (Int, String) -> Seq String)
-> (a -> Seq (Int, String)) -> a -> Seq String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Output -> Seq (Int, String)
forall w a. Writer w a -> w
execWriter (Output -> Seq (Int, String))
-> (a -> Output) -> a -> Seq (Int, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Output
forall a. TextMsg a => a -> Output
textPut
where
setIndent :: (Int, String) -> String
setIndent (Int
n, String
s) = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) Char
' ' String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
lexer :: Stream s Identity Char => T.GenTokenParser s () Identity
lexer :: GenTokenParser s () Identity
lexer = GenLanguageDef s () Identity -> GenTokenParser s () Identity
forall s (m :: * -> *) u.
Stream s m Char =>
GenLanguageDef s u m -> GenTokenParser s u m
T.makeTokenParser LanguageDef :: forall s u (m :: * -> *).
String
-> String
-> String
-> Bool
-> ParsecT s u m Char
-> ParsecT s u m Char
-> ParsecT s u m Char
-> ParsecT s u m Char
-> [String]
-> [String]
-> Bool
-> GenLanguageDef s u m
T.LanguageDef {
identStart :: ParsecT s () Identity Char
T.identStart = ParsecT s () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter ParsecT s () Identity Char
-> ParsecT s () Identity Char -> ParsecT s () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_'
, identLetter :: ParsecT s () Identity Char
T.identLetter = ParsecT s () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum ParsecT s () Identity Char
-> ParsecT s () Identity Char -> ParsecT s () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_'
, opStart :: ParsecT s () Identity Char
T.opStart = String -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":!#$%&*+./<=>?@\\^|-~"
, opLetter :: ParsecT s () Identity Char
T.opLetter = String -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":!#$%&*+./<=>?@\\^|-~"
, caseSensitive :: Bool
T.caseSensitive = Bool
True
, commentStart :: String
T.commentStart = String
"/*"
, commentEnd :: String
T.commentEnd = String
"*/"
, commentLine :: String
T.commentLine = String
"//"
, nestedComments :: Bool
T.nestedComments = Bool
True
, reservedNames :: [String]
T.reservedNames = []
, reservedOpNames :: [String]
T.reservedOpNames= []
}
symbol :: Stream s Identity Char => String -> Parsec s () ()
symbol :: String -> Parsec s () ()
symbol String
sym = ParsecT s () Identity String -> Parsec s () ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT s () Identity String -> Parsec s () ())
-> ParsecT s () Identity String -> Parsec s () ()
forall a b. (a -> b) -> a -> b
$ GenTokenParser s () Identity
-> String -> ParsecT s () Identity String
forall s u (m :: * -> *).
GenTokenParser s u m -> String -> ParsecT s u m String
T.symbol GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer String
sym
colon :: Stream s Identity Char => Parsec s () ()
colon :: Parsec s () ()
colon = ParsecT s () Identity String -> Parsec s () ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT s () Identity String -> Parsec s () ())
-> ParsecT s () Identity String -> Parsec s () ()
forall a b. (a -> b) -> a -> b
$ GenTokenParser s () Identity -> ParsecT s () Identity String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.colon GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
braces :: Stream s Identity Char => Parsec s () a -> Parsec s () a
braces :: Parsec s () a -> Parsec s () a
braces = GenTokenParser s () Identity
-> forall a. ParsecT s () Identity a -> ParsecT s () Identity a
forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
T.braces GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
natural :: (Integral a, Stream s Identity Char) => Parsec s () a
natural :: Parsec s () a
natural = Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> ParsecT s () Identity Integer -> Parsec s () a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity -> ParsecT s () Identity Integer
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
T.natural GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
integer :: (Integral a, Stream s Identity Char) => Parsec s () a
integer :: Parsec s () a
integer = Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> ParsecT s () Identity Integer -> Parsec s () a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity -> ParsecT s () Identity Integer
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
T.integer GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
float :: Stream s Identity Char => Parsec s () Double
float :: Parsec s () Double
float = (Integer -> Double)
-> (Double -> Double) -> Either Integer Double -> Double
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Integer -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double -> Double
forall a. a -> a
id (Either Integer Double -> Double)
-> ParsecT s () Identity (Either Integer Double)
-> Parsec s () Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity
-> ParsecT s () Identity (Either Integer Double)
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m (Either Integer Double)
T.naturalOrFloat GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
stringLiteral :: Stream s Identity Char => Parsec s () String
stringLiteral :: Parsec s () String
stringLiteral = GenTokenParser s () Identity -> Parsec s () String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.stringLiteral GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer
getRead :: forall a s . (Read a, Stream s Identity Char) => String -> Parsec s () a
getRead :: String -> Parsec s () a
getRead String
name = Parsec s () a -> Parsec s () a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Parsec s () a -> Parsec s () a) -> Parsec s () a -> Parsec s () a
forall a b. (a -> b) -> a -> b
$ do
String
v <- Parsec s () String -> String -> Parsec s () String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar (GenTokenParser s () Identity -> Parsec s () String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.identifier GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer) String
name
case String -> Maybe a
forall a. Read a => String -> Maybe a
readMaybe String
v of
Just a
r -> a -> Parsec s () a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
Maybe a
Nothing -> String -> Parsec s () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parsec s () a) -> String -> Parsec s () a
forall a b. (a -> b) -> a -> b
$ String
"can't parse " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v
getScalar :: Stream s Identity Char => Parsec s () a -> String -> Parsec s () a
getScalar :: Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () a
parser String
name = String -> Parsec s () ()
forall s. Stream s Identity Char => String -> Parsec s () ()
symbol String
name Parsec s () () -> Parsec s () () -> Parsec s () ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () ()
forall s. Stream s Identity Char => Parsec s () ()
colon Parsec s () () -> Parsec s () a -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () a
parser
getSubMessage :: (Stream s Identity Char, TextMsg a) => String -> Parsec s () a
getSubMessage :: String -> Parsec s () a
getSubMessage String
name = String -> Parsec s () ()
forall s. Stream s Identity Char => String -> Parsec s () ()
symbol String
name Parsec s () () -> Parsec s () a -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () a -> Parsec s () a
forall s a.
Stream s Identity Char =>
Parsec s () a -> Parsec s () a
braces Parsec s () a
forall a s. (TextMsg a, Stream s Identity Char) => Parsec s () a
textGet
messageGetText :: (TextMsg a, Stream s Identity Char) => s -> Either String a
messageGetText :: s -> Either String a
messageGetText s
s = case Parsec s () a -> String -> s -> Either ParseError a
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse (Parsec s () a
forall a s. (TextMsg a, Stream s Identity Char) => Parsec s () a
textGet Parsec s () a -> ParsecT s () Identity () -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT s () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) String
"<protobuf>" s
s of
Left ParseError
e -> String -> Either String a
forall a b. a -> Either a b
Left (ParseError -> String
forall a. Show a => a -> String
show ParseError
e)
Right a
m -> a -> Either String a
forall a b. b -> Either a b
Right a
m