|
|
|
|
|
by tel
4483 days ago
|
|
For the extra curious, here's a little Parser (untested, poor design, but generally the right idea) newtype Parser a = Parser { unParser :: MaybeT (State String) a }
deriving ( Functor, Applicative, Alternative,
Monad, MonadPlus, MonadTrans,
MonadState String )
-- why write boilerplate when the
-- compiler will for you?
runParser :: Parser a -> String -> Maybe a
runParser input = flip evalStateT input . runMaybeT
-- | Parses a single character if it passes a predicate
satisfy :: (Char -> Bool) -> Parser Char
satisfy p = do
(c:cs) <- get
guard (p c)
put cs
return c
char :: Char -> Parser Char
char c = satisfy (== c)
-- | Parses a whole string
string :: String -> Parser String
string = mapM char
-- | Converts a parser to be surrounded by parentheses
parens :: Parser a -> Parser a
parens p = char '(' *> p <* char ')'
|
|