Skip to content

Instantly share code, notes, and snippets.

@evansb
Created August 11, 2014 11:28
Show Gist options
  • Save evansb/fb01f4fd6dba91da5ced to your computer and use it in GitHub Desktop.
Save evansb/fb01f4fd6dba91da5ced to your computer and use it in GitHub Desktop.
3 lines Parser in Haskell (Line 9,11,12)
import Control.Monad.State.Lazy
import Control.Monad.Error
import Control.Monad.Identity
import Control.Applicative
import Data.Char
-- Begin parser
type Parser a = StateT String (ErrorT String Identity) a
parse:: Parser a -> String -> Either String (a, String)
parse p = runIdentity . runErrorT . runStateT p
-- End of parser.. That's 3 lines..
-- Example time!
satisfy :: String -> (Char -> Bool) -> Parser Char
satisfy desc f = get
>>= \s -> case s of
[] -> throwError "Unexpected EOF"
(x : xs) -> if f x then put xs >> return x
else throwError
("Expected " ++ desc ++ " here")
char :: Parser Char
char = satisfy "Alphabet" isAlpha
digit :: Parser Int
digit = digitToInt <$> satisfy "Digit" isDigit
-- Combine'em
digitThenChar :: Parser String
digitThenChar = (\d c -> show d ++ [c]) <$> digit <*> char
-- Test'em
main :: IO ()
main = mapM_ print [parse digitThenChar "2DHehehehe",
parse digitThenChar "WhoopsErrorHere"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment