[Haskell-cafe] Badly designed Parsec combinators?

Daniel Fischer daniel.is.fischer at web.de
Sun Feb 12 07:57:07 EST 2006


Am Sonntag, 12. Februar 2006 04:23 schrieb Juan Carlos Arevalo Baeza:
>    So... I see no reason why someone can't just do it themselves, but...
> I was playing around with Parsec (as included in GHC 6.4.1), and I found
> two functions that are... not quite what I believe they should be.
>
> optional :: GenParser tok st a -> GenParser tok st ()
> optional p          = do{ p; return ()} <|> return ()
>
>    Now, this completely loses the result of the optional parser. Better
> would be:
>
> optional :: GenParser tok st a -> GenParser tok st (Maybe a)
> optional p          = do{ x <- p; return (Just x) } <|> return Nothing
>

Hmm, I haven't used Parsec very much yet, but so far, whenever the result of 
an optional parser (mostly a '-'-sign) mattered, I use e.g.

option ' ' (char '-').

Your above parser would be

option Nothing (fmap Just p) -- or you might use liftM.

Both are easy enough. If you think the naming is unfortunate, I wouldn't 
flatly contradict, but it's too late now, I believe.

>    Same thing with manyTill:
>
> manyTill :: GenParser tok st a -> GenParser tok st end -> GenParser tok
> st [a]
> manyTill p end      = scan
>                     where
>                       scan  = do{ end; return [] }
>                             <|>
>                               do{ x <- p; xs <- scan; return (x:xs) }
>
>    Better:
>
> manyTill :: GenParser tok st a -> GenParser tok st end -> GenParser tok
> st ([a], end)
> manyTill p end      = scan
>                 where
>                   scan  = do{ endr <- end; return ([], endr) }
>                         <|>
>                           do{ x <- p; (xs, endr) <- scan; return (x:xs,
> endr) }
>
>    Is there any reason I can't see why they are the way they are?
>
> JCAB

With manyTill, I tend to agree with you; sometimes (not often) I would need 
the result of end, too. So far, this meant that I didn't use Parsec then, but 
wrote my own library, including a 'test' combinator where 'test p' would 
succeed or fail as p would, but not consume any input in either case, so I 
would use 'manyTill p (test end)' and afterwards endr <- end. Since changing 
manyTill now would be unfeasible, I wonder if including such a 'test' would 
be a good idea (danger: somebody might use 'many (test p)') or if providing 
your parser (under the name manyTillPair or something) would be better.

Cheers,
Daniel
-- 

"In My Egotistical Opinion, most people's C programs should be
indented six feet downward and covered with dirt."
	-- Blair P. Houghton



More information about the Haskell-Cafe mailing list