import "Prelude" """ Parser is a function from a string and a position in the string to a possible semantics of a substring and the end of the substring. """ data Parser a = Parser (String -> Integer -> Maybe (a, Integer)) runParser :: Parser a -> String -> Integer -> Maybe (a, Integer) runParser (Parser f) = f instance Functor Parser where fmap f (Parser p) = Parser (\input pos -> match p input pos with Nothing -> Nothing Just (a, newPos) -> Just (f a, newPos) ) instance Monad Parser where return x = Parser (\_ pos -> Just (x, pos)) (pa >>= f) = Parser (\input pos -> match runParser pa input pos with Nothing -> Nothing Just (a, newPos) -> runParser (f a) input newPos ) (|||) :: Parser a -> Parser a -> Parser a Parser a ||| Parser b = Parser (\input pos -> match a input pos with Nothing -> b input pos Just x -> Just x ) keyword :: String -> Parser () keyword word = Parser (\input pos -> if regionMatches word 0 input pos (length word) then Just ((), pos + (length word)) else Nothing ) data List a = Nil | Cons a (List a) listSepL :: Parser () -> Parser a -> Parser (List a) listSepL sep el = mdo head <- el tail <- (sep >> listSepL sep el) ||| return Nil return (Cons head tail) fromList :: List a -> [a] fromList = unfoldr gen where gen Nil = Nothing gen (Cons h t) = Just (h, t) listSep :: Parser () -> Parser a -> Parser [a] listSep sep el = fmap fromList (listSepL sep el) aOrB = (keyword "a" >> return "a") ||| (keyword "b" >> return "b") myParser = listSep (keyword ",") aOrB main = show (runParser myParser "a,b,b,a" 0) -- Just (["a", "b", "b", "a"], 7)