module HaskellWorks.Data.String.Parse where import Control.Monad import Control.Applicative newtype Parser a = Parser { parse :: String -> [(a, String)] } runParser :: Parser a -> String -> a runParser m s = case parse m s of [(res, [])] -> res [(_, _)] -> error "Parser did not consume entire stream." _ -> error "Parser error." item :: Parser Char item = Parser $ \s -> case s of [] -> [] (c:cs) -> [(c,cs)] bind :: Parser a -> (a -> Parser b) -> Parser b bind p f = Parser $ \s -> concatMap (\(a, s') -> parse (f a) s') $ parse p s unit :: a -> Parser a unit a = Parser (\s -> [(a,s)]) instance Functor Parser where fmap f (Parser cs) = Parser (\s -> [(f a, b) | (a, b) <- cs s]) instance Applicative Parser where pure = unit (Parser cs1) <*> (Parser cs2) = Parser (\s -> [(f a, s2) | (f, s1) <- cs1 s, (a, s2) <- cs2 s1]) instance Monad Parser where (>>=) = bind instance MonadPlus Parser where mzero = failure mplus = combine instance Alternative Parser where empty = mzero (<|>) = option combine :: Parser a -> Parser a -> Parser a combine p q = Parser (\s -> parse p s ++ parse q s) failure :: Parser a failure = Parser (const []) option :: Parser a -> Parser a -> Parser a option p q = Parser $ \s -> case parse p s of [] -> parse q s res -> res char :: Char -> Parser Char char c = do d <- item if c == d then return c else failure