[Haskell-cafe] nested parsing?

Evan Laforge qdunkan at gmail.com
Fri Jul 4 21:02:18 EDT 2008


Here's something I occasionally want to do with parsec:

msg = do
    header
    body <- manyTill anyToken footer
    vals <- sub_parse parse_body (preprocess body)
    ...

By coincidence I notice that perhaps the "manyTill stack overflow"
thread could use something like this too.  So I wrote:

sub_parse :: Parsec.GenParser subtok st a -> [subtok]
    -> Parsec.GenParser tok st a
sub_parse parser toks = do
    st <- Parsec.getState
    pos <- Parsec.getPosition
    case Parsec.runParser (Parsec.setPosition pos >> parser) st "" toks of
        Left err -> fail (show err)
        Right val -> return val
    -- oh yes, and I'd set the state to the final sub parse state too

In this particular case, I found another solution that didn't need
sub-parsing, so I haven't actually tested this much.  In particular
parsec doesn't let me throw a "raw" exception so I have to use "fail"
and the error msgs look ugly.  In addition, if 'preprocess' adds or
removes tokens from 'body', I have to do something awkward like pass
tokens around as (pos, tok).

But come to think of it, I've done this pattern before, where I invoke
a sub-monad and (mostly) splice it in with the current one, in one
case to allow the submonad to be monomorphic on the monad type while
calling monad remains polymorphic, in another case so I can run the
submonad from dynamically loaded code which must be monomorphic but
splice its results into the polymorphic calling monad... this is
similar to the first one I guess.

It seems somewhat similar to what catchError is doing.


More information about the Haskell-Cafe mailing list