
I want to write a parser for a Haskell-like type language. Amongst other things this means having a symbol table of top-level declarations. So for instance I want to be able to write in my type language:
type Foo = Bar Int
data Bar a = Bar String a
data ParsedTypeExpr = ParsedTypeExpr {parsedBaseType :: String,
I can come up with a parser that identifies "Bar" in the type synonym as the name of another type. I could define a type to return from the parser which just has that as a string, but then I would have to write another data type which is essentially the same but replaces the string name with the actual data type, and a mapping function to use a symbol table to convert one into the other, like this: parsedTypeArgs :: [String]}
data TypeExpr = TypeExpr {baseType :: MyType, typeArgs :: [String]}
convertTypeExpr :: (String -> MyType) -> ParsedTypeExpr -> TypeExpr
I want to short-circuit this by looking up the definition of Bar in the parser. But that requires the symbol table to exist during the parse. I have to admit I haven't quite got my head around MonadFix yet, but if I understand it correctly I should be able to have a top level parser something like this:
parseDeclarations :: Parser [Declaration] parseDeclarations = mdo decls <- many ParseDeclaration symbols let symbols = makeSymbolTable decls return decls
Unfortunately GenParser isn't an instance of MonadFix, so this won't work. Is there a good reason why GenParser can't be an instance of MonadFix? If not, what would the instance declaration be? Thanks, Paul.