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.