hw-string-parse-0.0.0.2: src/HaskellWorks/Data/String/Parse.hs
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 = return
(Parser cs1) <*> (Parser cs2) = Parser (\s -> [(f a, s2) | (f, s1) <- cs1 s, (a, s2) <- cs2 s1])
instance Monad Parser where
return = unit
(>>=) = 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