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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With