[Haskell-cafe] parsec3 pre-release [attempt 2]

Philippa Cowderoy flippa at flippac.org
Mon Feb 4 22:11:11 EST 2008


On Sun, 3 Feb 2008, Antoine Latter wrote:

> Another picky nit:
>
> The monad transformer type is defined as such:
>
> > data ParsecT s u m a
> >     = ParsecT { runParsecT :: State s u -> m (Consumed (m (Reply s u
a))) }
>
> with the Consumed and reply types as:
>
> > data Consumed a  = Consumed a
> >                  | Empty !a
>
> > data Reply s u a = Ok !a !(State s u) ParseError
> >                  | Error ParseError
>
> What's the advantage of having a double-wrapping of the base monad `m'
> over the simpler type:
>
> data ParsecT s u m a
>     = ParsecT { runParsecT :: State s u -> m (Consumed (Reply s u a)) }
>

It's a necessary part of how Parsec works - both the Consumed and the
Reply depend on the input stream, which is now generated from within the
base monad. The Consumed result is evaluated in advance of the Reply, so
keeping the computations separate preserves an important piece of
laziness as m could be a strict monad.

For now it's probably a good idea to look for issues that're visible to
client code? Turning Parsec into a transformer was long considered an
invitation to serious confusion, so it's not surprising that a few things
look odd and a few others can be generalised in ways that aren't
immediately obvious.

-- 
flippa at flippac.org

"The reason for this is simple yet profound. Equations of the form
x = x are completely useless. All interesting equations are of the
form x = y." -- John C. Baez




More information about the Haskell-Cafe mailing list