module Parser (Parser, main) where -- import Types import Data.Char (isDigit, isSpace, isUpper, isLower, isAlphaNum) import Control.Applicative import Data.Maybe import Data.Functor import Text.ParserCombinators.ReadP takeWhileSplit :: (t -> Bool) -> [t] -> ([t], [t]) takeWhileSplit _ [] = ([], []) takeWhileSplit f (x:xs) | f x = (x:collected, rest) | otherwise = ([], xs) where (collected, rest) = takeWhileSplit f xs newtype Parser a = Parser { runParser :: String -> (String, Maybe a) } instance Functor Parser where fmap f (Parser p) = Parser $ \s -> let (s', mf) = p s in (s', f <$> mf) instance Applicative Parser where pure x = Parser $ \s -> (s, Just x) Parser pf <*> Parser px = Parser $ \s -> let (s1, mf) = pf s (s2, mx) = px s1 in (s2, mf <*> mx) instance Alternative Parser where empty = Parser $ \s -> (s, Nothing) Parser p <|> Parser q = Parser $ \s -> case (p s, q s) of (lhs@(_, Just _), _) -> lhs (_, rhs) -> rhs parseDigit :: Parser Char parseDigit = Parser p where p "" = ("", Nothing) p (x:xs) | x `elem` ['0'..'9'] = (xs, Just x) | otherwise = (xs, Nothing) parseInt :: Parser Integer parseInt = read <$> some parseDigit data Unary = Output | Prompt | Bang deriving(Show) parseUnary :: Parser Unary parseUnary = string "OUTPUT" $> Output <|> string "PROMPT" $> Prompt <|> char '!' $> Bang main = let (_, x) = runParser parseUnary "OUTPUT" in print (fromJust x)