I was reading GADT introduction here and it I found the idea of restricting programmer to create only right type of syntax tree great, and I put this idea into my simple lambda calculus interpreter, but later I realized that I can't parse a string to this syntax tree, because one parse function needs to return different types of syntax tree, depending on input. Here's an example:
{-# LANGUAGE GADTs #-}
data Ident
data Lambda
data Application
data Expr a where
Ident :: String -> Expr Ident
Lambda :: Expr Ident -> Expr a -> Expr Lambda
Application :: Expr a -> Expr a -> Expr Application
Before using GADTs, I was using this:
data Expr = Lambda Expr Expr
| Ident String
| Application Expr Expr
GADTs are great advantage here, bacuse now I can't create invalid syntax trees like Lambda (Application ..) ..
.
But with GADTs, I couldn't parse a string and create parse tree. Here are parser for Lambda, Ident, and Application expressions:
ident :: Parser (Expr Ident)
ident = ...
lambda :: Parser (Expr Lambda)
lambda = ...
application :: Parser (Expr Application)
application = ...
Now the problem is:
expr = choice [ident, application, lambda]
This obviously doesn't work, since each parser is returning different types.
So, is there a way to parse a string and create a syntax tree, with GADTs ?