I'm working through the Write Yourself a Scheme tutorial, and one code block made me wonder about the difference between bind and assignment:
parseAtom = do first <- letter <|> symbol
rest <- many (letter <|> digit <|> symbol)
let atom = first:rest
return $ case atom of
"#t" -> Bool True
"#f" -> Bool False
_ -> Atom atom
Why let atom =
instead of atom <-
? Thus, I tried:
parseAtom = do first <- letter <|> symbol
rest <- many (letter <|> digit <|> symbol)
atom <- first : rest
return $ case atom of
"#t" -> Bool True
"#f" -> Bool False
_ -> Atom atom
And I get the compile error:
Couldn't match expected type `[Char]'
against inferred type `Text.Parsec.Prim.ParsecT
String () Data.Functor.Identity.Identity Char'
In a stmt of a 'do' expression: atom <- first : rest
I can't figure precisely what this means, which is probably due to an imprecise understanding of do
or monads. (I've read Learn You a Haskell along with various other monad/do tutorials, and other SO questions note that indentation oftens causes issues here, but I think I'm indenting correctly)