[Haskell-cafe] Parsec question

Dave Tapley dukedave at gmail.com
Thu Jun 21 04:51:35 EDT 2007


I find it's good for the soul to remember what the do notation is doing for us.

Also I'm with Einstein on "You do not really understand something
unless you can explain it to your grandmother"  :)

Personally I think (in this instance) your three 'Parser a' functions
read nicer as:

> primary = (identifier >>= (return . PrimaryIdentifier)) <|> (stringLiteral >>= (return . PrimaryLiteral))
> identifier = (many1 letter) >>= (return . Identifier)
> stringLiteral = (char '\'') >> (manyTill anyChar (char '\'')) >>= (return . StringLiteral)

Looking at them in this form Tomek's point should seem clear now,
especially when we look at the type signature for liftM:

liftM :: Monad m => (a1 -> r) -> m a1 -> m r

So we can (marginally) shorten down to:

> primary = (liftM PrimaryIdentifier identifier) <|> (liftM PrimaryLiteral stringLiteral)
> identifier = liftM Identifier (many1 letter)
> stringLiteral = liftM StringLiteral ((char '\'') >> (manyTill anyChar (char '\'')))


You might like:
http://syntaxfree.wordpress.com/2006/12/12/do-notation-considered-harmful/

Dave,

On 21/06/07, Tomasz Zielonka <tomasz.zielonka at gmail.com> wrote:
> On Thu, Jun 21, 2007 at 03:34:54PM +0930, Levi Stephen wrote:
> > Is there a way through combining types/parsers that the double do
> > block in primary could be avoided?
> >
> > I understand it's necessary right now because the parsers identifier
> > and stringLiteral return different types, so I can't just write:
> >
> > >i <- identifier <|> stringLiteral
>
> You can use the fact that (GenParser tok st) is a monad and use liftM:
>
>     i <- liftM PrimaryIdentifier identifier <|> liftM PrimaryLiteral stringLiteral
>
> I often find it convenient to use "choice" instead of <|> for long more
> complicated alternatives, for example like this:
>
> primary =
>     choice
>         [ do
>             i <- identifier
>             return $ PrimaryIdentifier i
>         , do
>             l <- stringLiteral
>             return $ PrimaryLiteral l
>         ]
>
> > So, I'm not sure whether my types need work,
>
> I have a feeling that Identifier and Literal could just be type
> synonyms, because newtype's don't seem to be neccesary or beneficial
> here.  I could be wrong though - after all, I don't know your intentions
> and the rest of the program.
>
> Best regards
> Tomek
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list