In this question Will's answer states that the following code (let's call it code A):
reverse2lines :: IO ()
reverse2lines =
do line1 <- getLine
line2 <- getLine
putStrLn (reverse line2)
putStrLn (reverse line1)
can be transformed into the following (let's call it code B) :
reverse2lines =
do { line1 <- getLine ;
do { line2 <- getLine ;
do { putStrLn (reverse line2) ;
do { putStrLn (reverse line1) } } } }
I am confused. I understand, for example, that
addOneInt :: IO ()
addOneInt = do line <- getLine
putStrLn (show (1 + read line :: Int))
can be transformed into:
addOneInt' :: IO ()
addOneInt' = getLine >>= \line ->
putStrLn (show ( 1 + read line :: Int))
But I don't understand how the nested do transformation works. In other words, I don't understand how one arrives from code A to code B ? What are the rules governing this transformation ?
Where are these rules described / explained / specified ?
Could someone please explain what is going on here with this (codeA to codeB) transformation ?
For example, what does do { command1; do {command2 } } mean ? How should I interpret that ? What is its definition ?
In other words,
what is the difference between
do {command1;command2} and
do {command1; do {command2}} ?
Furthermore, what is the difference between
do {command1; do{command2};command3} and
do {command1;do {command2; do {command3}}} ?
Thanks for reading.