could easily put 2 different values into `a` on each line. Of course, technically everything is still correct, and getA still returns same result for each call.
Yes. You're free to rename second a to b. The point I wanted to make is that it's the same getA, but anyone reading the code should understand that result binded to a and b will be different.
Depending on the monad. If you are in Reader and getA == ask, a and b will have the same value. If you are in IO and getA == getLine, a and b may be different.
The whole point I was talking about is that as soon as you're in monad, referential transparency becomes a bit a "lie", and a <- getA, b <- getA becomes non just analogous to a = getA(); b = getA();, but even worse in "referential transparency" sense.
Referential transparency is not a lie; getA is just a value. It could be substituted for its meaning without altering the program. For example, the following program:
foo = do
a <- getA
putStrLn ("Hello, " ++ a ++ "!")
where
getA = do putStrLn "What is your name?"
getLine
Is equivalent to:
bar = do
a <- do putStrLn "What is your name?"
getLine
putStrLn ("Hello, " ++ a ++ "!")
Yes, that's exactly what I was sayint 2 comments upper this thread:
> The point I wanted to make is that it's the same getA, but anyone reading the code should understand that result binded to a and b will be different.
So, while referrential transparency is still in place, programmer who reads the code will most likely care not about getA's result, but rather what will a and b get binded to, and in those terms it's just the same as good old
That said, I agree that Haskell code is typically dense, and suffers from readability problems.