combining a trifecta parser with FreshMT from unbound

I can relatively easily combine a trifecta parser with some state: -- imports, language pragmas omitted here newtype InnerParser a = InnerParser { runInnerParser :: Parser a } deriving (Functor , Monad , Applicative , Alternative , Parsing , CharParsing , MonadPlus ) data PiState = PiState { foobar :: Integer -- ...some more stuff... } type PiParser = StateT PiState InnerParser instance TokenParsing PiParser where someSpace = buildSomeSpaceParser (skipSome (satisfy isSpace)) $ commentStart .~ "{-" $ commentEnd .~ "-}" $ commentLine .~ "--" $ commentNesting .~ True $ emptyCommentStyle idStyle = styleStart .~ letter $ styleLetter .~ (alphaNum <|> oneOf "_'") $ styleReserved .~ HS.fromList ["refl" ,"ind" ,"Type" -- ... ] $ emptyIdents identifier :: PiParser String identifier = token $ ident $ idStyle -- etc. This is the approach taken in Idris e.g. and it works, as I understand, because the trifecta/parsers type classes involved (CharParsing etc) are "already prepared" for attaching a StateT monad transformer: there are instances defined for all the usual transformers: StateT, ReaderT, RWST etc. I can easily add more convenient type classes, having them derived for my InnerParser: LookAheadParsing, DeltaParsing etc. Now when I want to use FreshMT from the unbound package instead of StateT, things get much more complicated. I don't really care at this point if with a type synonym type PiParser = FreshMT InnerParser or as a newtype wrapper (deriving as much as I can automatically) newtype PiParser a = P { runP :: FreshMT InnerParser a } deriving (Monad, Functor, Applicative) Anyway, I need to provide all these instances by hand (CharParsing, Alternative etc), am still struggling with the details (and might have more questions in this regard), even though FreshMT really is just defined in terms of StateT http://hackage.haskell.org/package/unbound-0.4.3.1/docs/src/Unbound-LocallyN... So I wonder, if there is an easier way to approach this, have some more instances derived automatically ? (Basically I just want to get Stephanie Weirichs pi-forall language working with trifecta instead of parsec, cf. this years' OPLSS) I can provide complete running code (with all the imports etc) if necessary. Thanks. -Andreas

OK, I have made some progress, and have uploaded two programs to lpaste.net * one that works: trifecta + unbound, works: http://lpaste.net/108457 * and one that doesn't trifecta + unbound, fails http://lpaste.net/108458 the working version is simpler, in that it defines PiParser just as a type synonym type PiParser = FreshMT InnerParser maybe I should be happy already that I got that working, e.g.
parseTest (runInnerParser $ runFreshMT $ whiteSpace *> many identifier) " wow {- bla -} this rocks" ["wow","this","rocks"]
to install: cabal install trifecta + unbound in a sandbox e.g. Now in the second version, I have in addition wrapped the FreshMT in a newtype newtype FreshT m a = F { runF :: FreshMT m a } deriving (Monad, Functor, Applicative, MonadPlus, MonadTrans) type PiParser = FreshT InnerParser While this might not be necessary in this simple case here, I can imagine situations, where doing so might come in handy. Consequently have to add a few more instances for the parser: instance CharParsing PiParser where etc. and of course I need an additional step of unwrapping with runF runInnerParser $ runFreshMT $ runF someparser (In both versions TokenParser is defined on the PiParser) I would expect that I can parse something like the above test string similarily, but unfortunately this is not the case:
parseTest (runInnerParser $ runFreshMT $ runF (whiteSpace *> many identifier)) " oh too {- bla -} bad" []
I can at most parse one letter:
parseTest (runInnerParser $ runFreshMT $ runF (whiteSpace *> identifier)) "oh too {- bla -} bad" "o"
I don't really see, how wrapping the FreshMT in a newtype harms the parser? Thanks in advance -Andreas
participants (1)
-
Andreas Reuleaux