[Haskell-cafe] How to use notFollowedBy function in Parsec

Sara Kenedy sarakenedy at gmail.com
Sun Nov 20 21:27:53 EST 2005


Thanks for your solution. However, when I try this,

>     str1 :: Parser String
>    str1 = do str <- many anyToken
>	          notFollowedBy' semi
>                 return str

>     notFollowedBy' :: Show a => GenParser tok st a -> GenParser tok st ()
>     notFollowedBy' p  = try $ join $  do  a <- try p
>                                                         return (unexpected (show a))
>                                                  <|>
>                                                  return (return ())
>      run:: Show a => Parser a -> String -> IO()

>      run p input

>	= case (parse p "" input) of

>		Left err -> do {putStr "parse error at " ;print err}

>		Right x -> print

When I compile, it still displays ";" at the end of the string.

  Parser> run str1 "Hello ;"
  "Hello ;"

The reason, as I think, because anyToken accepts any kind of token, it
considers ";" as token of its string. Thus, it does not understand
notFollowedBy' ???

Do you have any ideas about this ??? Thanks.


On 11/19/05, Andrew Pimlott <andrew at pimlott.net> wrote:
> On Sat, Nov 19, 2005 at 06:43:48PM -0500, Sara Kenedy wrote:
> > str1 :: Parser String
> > str1 = do {str <- many anyToken; notFollowedBy semi; return str}
> >
> > However, when I compile, there is an error.
> >
> > ERROR "Test.hs":17 - Type error in application
> > *** Expression     : notFollowedBy semi
> > *** Term           : semi
> > *** Type           : GenParser Char () String
> > *** Does not match : GenParser [Char] () [Char]
>
> The problem is that notFollowedBy has type
>
>     notFollowedBy  :: Show tok => GenParser tok st tok -> GenParser tok st ()
>
> ie, the result type of the parser you pass to notFollowedBy has to be
> the same as the token type, in this case Char.  (The reason for this
> type is obscure.)  But semi has result type String.  You could fix the
> type error by returning a dummy Char:
>
>     str1 = do {str <- many anyToken
>               ; notFollowedBy (semi >> return undefined)
>               ; return str}
>
> I think this will even work; however notFollowedBy is a pretty
> squirrelly function.  There was a discussion about it:
>
>     http://www.haskell.org/pipermail/haskell/2004-February/013621.html
>
> Here is a version (which came out of that thread) with a nicer type,
> that probably also works more reliably (though I won't guarantee it):
>
>     notFollowedBy' :: Show a => GenParser tok st a -> GenParser tok st ()
>     notFollowedBy' p  = try $ join $  do  a <- try p
>                                           return (unexpected (show a))
>                                       <|>
>                                       return (return ())
>
> Andrew
>


More information about the Haskell-Cafe mailing list