arrows

Wolfgang Jeltsch wolfgang@jeltsch.net
Fri, 13 Dec 2002 00:07:13 +0100


On Saturday, 2002-12-07, 03:42, CET, Ashley Yakeley wrote:
> At 2002-12-06 15:57, Wolfgang Jeltsch wrote:
> > I cannot see how this relatively simple representation can be used to
> > describe certain parsers. If I would use Identity for baseMonad, I wo=
uld
> > have a type for simple parsers. MyParser Identity would essentially b=
e
> > token -> output.
>
> You can't use Identity for baseMonad. You would need to use something t=
hat
> managed a stream. The idea is that your source is something of type
> "baseMonad token", and by repeatedly calling source, you pull off indiv=
idual
> tokens.

Hello Ashley,

now I understand what you mean. Obviously you misinterpreted the meaning =
of=20
baseMonad in
    Parser baseMonad token output
where Parser means the parser type I described some mails ago. In fact,
    Parser baseMonad token output
doesn't correspond to your
    MyParser baseMonad token output
but to
    forall s. MyParser (StateT s baseMonad) token output.
This shows that I could define Parser via
    newtype
        Monad baseMonad =3D>
        Parser bm t o =3D Parser (forall s. StateT s bm t -> StateT s bm =
o)
instead of the "complicated way" I did.

The reason I didn't use this "simple implementation" is that with this=20
implementation the same state transformer may be invoked on the same stat=
e=20
multiple times. For example, consider a parser
    tokenProvider :: Parser Maybe Char token
and two parsers
    tokenConsumerOne :: Parser Maybe token output
and
    tokenConsumerTwo :: Parser Maybe token output.
Now let's combine them in the term
    tokenProvider >>> (tokenConsumerOne `mplus` tokenConsumerTwo).
The "simple" Parser implementation would, obviously, define (>>>) and mze=
ro=20
the following way:
    Parser parserOneFun >>> Parser parserTwoFun
        =3D Parser (parserTwoFun . parserOneFun)
    Parser parserOneFun `mzero` Parser parserTwoFun
        =3D Parser (\source -> parserOneFun source `mplus` parserTwoFun s=
ource)
Now, if tokenConsumerOne fails (indicated by Nothing), tokenProvider woul=
d=20
parse tokens during the execution of tokenConsumerOne and parse the same=20
tokens from the same input again during the execution of tokenConsumerTwo=
=2E=20
Using my "complicated implementation", the tokens parsed during the execu=
tion=20
of tokenConsumerOne are reused during the execution of tokenConsumerTwo.

> [...]

What makes your implementation interesting, is the fact that it is far mo=
re=20
general than mine because it isn't restricted to state transformers. But =
I=20
can imagine that I don't need this extra generality. And for many monads =
m=20
(like, e.g., Identity or []) the type MyParser m is just not what you wou=
ld=20
call a parser.

Wolfgang