From Text.Parsec.Token
:
lexeme p = do { x <- p; whiteSpace; return x }
It appears that lexeme takes a parser p and delivers a parser that has the same behavior as p, except that it also skips all the trailing whitespace. Correct?
Then how come the following does not work:
constant :: Parser Int
constant = do
digits <- many1 digit
return (read digits)
lexConst :: Parser Int
lexConst = lexeme constant
The last line results in the following error message:
Couldn't match expected type `ParsecT
String () Data.Functor.Identity.Identity Int'
with actual type `ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0'
Expected type: Parser Int
Actual type: ParsecT s0 u0 m0 a0 -> ParsecT s0 u0 m0 a0
In the return type of a call of `lexeme'
In the expression: lexeme constant
What am I doing wrong?
You misunderstood the documentation, the
lexeme
exported fromText.Parsec.Token
is a field of aGenTokenParser s u m
, so the type isand you haven't supplied the
GenTokenParser
argument inlexeme constant
.You need to create a
GenTokenParser
from aGenLanguageDef
(typically withmakeTokenParser
) first to use itslexeme
field.The
lexeme
function is an accessor into aGenTokenParser
record of parsers generated bymakeTokenParser
, so you need to apply it to such a record to get at it. One common way of doing this is to use record wildcards, e.g.This will bring
lexeme
and all the other parsers into scope already applied to the record, so you can use it like you were trying to do.