I've read a few books on Haskell but haven't coded in it all that much, and I'm a little confused as to what Haskell is doing in a certain case. Let's say I'm using getLine so the user can push a key to continue, but I don't really want to interpret that person's input in any meaningful way. I believe this is a valid way of doing this:
main = do
_ <- getLine
putStrLn "foo"
I understand the basic gist of what's this is doing. getLine returns an IO String, and putStrLn takes a String and returns IO (), so if I theoretically wanted to print what the user typed into the console, I'd basically utilize the >>= operator from the Monad class. In my case, I believe my code is equivalent to getLine >> putStrLn "foo" since I'm discarding the return value of getLine.
However, what if I do this instead?
main = do
let _ = getLine
putStrLn "foo"
In this case, we're setting up a sort of lambda to work with something that will take an IO String, right? I could write a printIOString function to print the user's input and that would work fine. When I'm not actually using that IO String, though, the program behaves strangely... getLine doesn't even prompt me for input; the program just prints out "foo".
I'm not really sure what the "desugared" syntax would be here, or if that would shed some light on what Haskell is doing under the hood.