fork download
  1. module Main where
  2.  
  3. import qualified Data.ByteString.Char8 as BS
  4. import Data.Maybe (fromMaybe)
  5. import Data.Char (isSpace)
  6. import Control.Monad.State.Lazy
  7. import Control.Applicative
  8.  
  9. -----BEGIN PARSER-----
  10.  
  11. type Parser a = StateT BS.ByteString Maybe a
  12.  
  13. skipSpaces (x, s) = (x, BS.dropWhile isSpace s)
  14.  
  15. readInt :: Parser Int
  16. readInt = StateT $ fmap skipSpaces . BS.readInt
  17.  
  18. -----END PARSER------
  19.  
  20. -----BEGIN COMBINATORS-----
  21.  
  22. readPair :: Parser (Int, Int)
  23. readPair = do
  24. x <- readInt
  25. y <- readInt
  26. return (x, y)
  27.  
  28. readIntList :: Int -> Parser [Int]
  29. readIntList n = sequence $ replicate n readInt
  30.  
  31. readSizedList :: Parser [Int]
  32. readSizedList = readInt >>= readIntList
  33.  
  34. -----END COMBINATORS-----
  35.  
  36. -- Testing...
  37.  
  38. data Struct = Struct Int (Int, Int) [Int]
  39. deriving (Show)
  40.  
  41. orFail = fromMaybe (BS.pack "EPIC FAIL!!!\n")
  42.  
  43. parsePrint :: Show a => Parser a -> (BS.ByteString -> BS.ByteString)
  44. parsePrint parseMe = orFail . evalStateT (do x <- parseMe
  45. return $ BS.pack $ show x ++ "\n")
  46.  
  47. testPair = parsePrint (Struct <$> readInt <*> readPair <*> readSizedList)
  48.  
  49. main = BS.interact testPair
Success #stdin #stdout 0s 4688KB
stdin
1
2 3
4
5 6 7 8
stdout
Struct 1 (2,3) [5,6,7,8]