
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.
participants (1)
-
Evan Laforge