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

Andrew Pimlott andrew at pimlott.net
Sat Nov 19 22:58:31 EST 2005


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