
Mark Spezzano wrote:
How exactly do monads “solve” the problem of referential transparency? I understand RT to be such that a function can be replaced with a actual value.
Since a monad could potentially encapsulate any other value—say, data read from a keyboard—doesn’t that violate the assumption of RT on monads?
Or does RT ignore the encapsulated data and just view the “action” performed by the monad as the “value” of the monad?
The term "referential transparency" refers to functions and means that "equal arguments give equal results". For instance, there cannot be a function getChar :: () -> Char that reads input from the keyboard because referential transparency demands that the character returned must always be the same. Similarly, a function putChar :: Char -> () that prints a character on the screen cannot exist because we could replace every say putChar 'a' with () which does not output anything. Both values are equal, after all. However, functions getChar :: () -> IO Char putChar :: Char -> IO () are entirely feasible; the side effect has been pushed into the IO type constructor. In other words, getChar () :: IO Char is always the same IO action (reading a character from the keyboard) and putChar 'c' :: IO () is always the same IO action (printing 'c' on the screen). In other words, we have decomposed "function with side effect" = "pure function" + "side effect" -> + IO Regards, apfelmus -- http://apfelmus.nfshost.com