module Main where import qualified Data.ByteString.Char8 as BS import Data.Maybe (fromMaybe) import Data.Char (isSpace) import Control.Monad.State.Lazy import Control.Applicative -----BEGIN PARSER----- type Parser a = StateT BS.ByteString Maybe a skipSpaces (x, s) = (x, BS.dropWhile isSpace s) readInt :: Parser Int readInt = StateT $ fmap skipSpaces . BS.readInt -----END PARSER------ -----BEGIN COMBINATORS----- readPair :: Parser (Int, Int) readPair = do x <- readInt y <- readInt return (x, y) readIntList :: Int -> Parser [Int] readIntList n = sequence $ replicate n readInt readSizedList :: Parser [Int] readSizedList = readInt >>= readIntList -----END COMBINATORS----- -- Testing... data Struct = Struct Int (Int, Int) [Int] deriving (Show) orFail = fromMaybe (BS.pack "EPIC FAIL!!!\n") parsePrint :: Show a => Parser a -> (BS.ByteString -> BS.ByteString) parsePrint parseMe = orFail . evalStateT (do x <- parseMe return $ BS.pack $ show x ++ "\n") testPair = parsePrint (Struct <$> readInt <*> readPair <*> readSizedList) main = BS.interact testPair