I'm working through "Write yourself a scheme interpreter in 48 hours" and one exercise is to write a function using do notation. This is the function:开发者_开发知识库
parseNumber :: Parser LispVal
parseNumber = liftM (Number . read) $ many1 digit
I tried the following, but that didn't work:
parseNumber2 :: Parser LispVal
parseNumber2 = do digits <- many1 digit
return $ liftM $ (Number . read) digits
Never mind. I indented the code incorrectly
Once you've unpacked digits
, you don't need the liftM
anymore. So it's just:
return $ Number $ read digits
I hopped on the #haskell IRC channel and asked lambdabot:
11:25 < dmwit> ?src liftM
11:25 < lambdabot> liftM f m1 = do { x1 <- m1; return (f x1) }
11:27 < dmwit> ?src ($)
11:27 < lambdabot> f $ x = f x
(If you don't want to ask lambdabot, you can also ask Hoogle and click the source link in the documentation.)
So, let's fill in f
and m1
:
liftM (Number . read) $ many1 digit
={definition of ($)}
liftM (Number . read) (many1 digit)
={definition of liftM}
do { x1 <- (many1 digit); return ((Number . read) x1) }
={expand to layout form, eliminate redundant parentheses}
do
x1 <- many1 digit
return ((Number . read) x1)
You can write half a dozen variations of this of varying syntactic aesthetic, but here's my favorite, after expanding the definitions of (.)
and ($)
a few times:
={definitions of (.) and ($)}
do
x1 <- many1 digit
return . Number . read $ x1
精彩评论