haskell - An easy way to change the type of Parsec user state? -
i'm looking easy way combine 2 parts of parsect code have same stream , monad, different user state , outcome. function nice:
withuserstate :: u -> parsect s u m -> parsect s v m
the thing is, user state helpful in cases, need different states @ different times , don't want make states type bigger. have modify state somehow achieve this, or there function can't find @ moment?
edit:
i think alternative like
changeuserstate :: (u -> v) -> parsect s u m -> parsect s v m
parsec doesn't let directly out of box, can achieve using parsec's public api follows:
{-# language scopedtypevariables #-} import text.parsec changestate :: forall m s u v . (functor m, monad m) => (u -> v) -> (v -> u) -> parsect s u m -> parsect s v m changestate forward backward = mkpt . transform . runparsect mapstate :: forall u v . (u -> v) -> state s u -> state s v mapstate f st = st { stateuser = f (stateuser st) } mapreply :: forall u v . (u -> v) -> reply s u -> reply s v mapreply f (ok st err) = ok (mapstate f st) err mapreply _ (error e) = error e fmap3 = fmap . fmap . fmap transform :: (state s u -> m (consumed (m (reply s u a)))) -> (state s v -> m (consumed (m (reply s v a)))) transform p st = fmap3 (mapreply forward) (p (mapstate backward st))
note requires both forward , backward conversion between u
, v
. reason first need translate ambient state local state, run inner parser, convert back.
scopedtypevariables
, local type signatures there clarity — feel free remove them if like.
Comments
Post a Comment