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
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:
> data ParsedTypeExpr = ParsedTypeExpr {parsedBaseType :: String,
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.