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 <[EMAIL PROTECTED]> 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@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to