lambda-calculator-0.5.0: src/Language/Lambda/Parser.hs
module Language.Lambda.Parser (parseExpr) where
import Control.Monad
import Prelude hiding (abs, curry, id)
import Text.Parsec
import Text.Parsec.String
import Language.Lambda.Expression
parseExpr :: String -> Either ParseError (LambdaExpr String)
parseExpr = parse (whitespace *> expr <* eof) ""
expr :: Parser (LambdaExpr String)
expr = try app <|> term
term :: Parser (LambdaExpr String)
term = abs <|> var <|> parens
var :: Parser (LambdaExpr String)
var = Var <$> identifier
abs :: Parser (LambdaExpr String)
abs = curry <$> idents <*> expr
where idents = (symbol '\\') *> many1 identifier <* (symbol '.')
curry = flip (foldr Abs)
app :: Parser (LambdaExpr String)
app = chainl1 term (return App)
parens :: Parser (LambdaExpr String)
parens = symbol '(' *> expr <* symbol ')'
lexeme :: Parser a -> Parser a
lexeme p = p <* whitespace
whitespace :: Parser ()
whitespace = void . many . oneOf $ " \t"
identifier :: Parser String
identifier = lexeme ((:) <$> first <*> many rest)
where first = letter <|> char '_'
rest = first <|> digit
symbol :: Char -> Parser ()
symbol = void . lexeme . char