[Haskell-beginners] Problem with GADTs and Parsec
Brent Yorgey
byorgey at seas.upenn.edu
Sat Feb 8 20:15:19 UTC 2014
On Sat, Feb 08, 2014 at 08:10:18PM +0100, Lorenzo Tabacchini wrote:
>
> exprParser :: Parsec String u (Expr a)
> exprParser = parens exprParser
> <|> (reserved "true" >> return (Bool True))
> <|> (reserved "false" >> return (Bool False))
> <|> (stringLiteral >>= return . Text)
As Brandon explained, this type does not mean what you want: it
promises to be able to return *any* type of Expr, but then it goes and
tries to return *particular* types of Exprs. Of course, the type is a
lie: you will only be able to return specific types of Exprs, but you
can't know which ones in advance.
In my opinion, this is one of the few places where existential
wrappers are really what you want. If I were you, I would do
something like this:
data ExprE where
ExprE :: Expr a -> ExprE -- existentially hides the expression type
Now you can write your parser to return an ExprE, with the type of the
expression hidden inside. In order to be able to use the resulting
ExprE values, you will also want a function like
withExprE :: ExprE -> (Expr a -> r) -> r
withExprE (ExprE expr) k = k expr
-Brent
More information about the Beginners
mailing list