I'm going through Write Yourself a Scheme and am struck at the exercise 4 on this page.
How do I go about this? I've got this far, but have no idea whatsoever where the readHex
is supposed to go, must I liftM
it ? Do you case match the parser ?
parseNumber = liftM (Number . read) $ choice [many1 digit, char '#' >> oneOf "hd" >>= a]
where a f = case f of
'h' -> many1 digit
Also, I don't suppose you can apply <|>
on Parser LispVal
functions, right?
I've got this far, but have no idea whatsoever where the readHex is supposed to go, must I liftM it ?
Yes, since readHex
is most likely a pure function and liftM
lifts it into the monadic context of Parser
.
Since I don't quite understand what your local function a
is good for, I'm leaving it for now and simply use the functions parseDecimal
and parseHex
. In that case, you could write parseNumber
like so:
parseNumber :: Parser LispVal
parseNumber = liftM Number $ parseDecimal <|> parseHex
where parseDecimal :: Parser Integer
parseDecimal = liftM read $ many1 digit
parseHex :: Parser Integer
parseHex = liftM readHex $ char '#' >> ... -- parse hex value
Of course you can omit the type signatures, I just added them for clarity.
Also, I don't suppose you can apply <|> on Parser LispVal functions, right?
<|>
works for every Parser a
.
I recommend reading some material on parser combinators, i.e. the Parsec User Guide.