At 3:37 pm 16/3/98, Patrick Logan wrote:
>A discussion about referential transparency and I/O in Haskell popped
>up in Comp.lang.scheme. The example was something like:
>
>do
>  x <- getLine
>  y <- getLine
>
>...with...
>
>getLine :: IO String
>
>And so my question is what is the value of getLine? I had thought of
>it as sort of a "placeholder" or "indicator" to the IO monad to
>provide another chunk of the input to the function that follows
>getLine. So without the syntax of "do"...
>
>getLine >>= \s1 -> print s1 >> getLine >>= \s2 -> print s2
>
>...in my mind was read as "getLine indicates to the >>= function to
>bind some input to s1, and then getLine indicates to the >>=
>function to bind some more input to s2".
>
>But do x and y, above, have different values?

Yes, they do, but note that the two occurrences of "getLine" have the
same value: they're functions from states to states and values
(the state is what's been captured and hidden in the IO monad).
So, what's happened is that you've applied the same function
(getLine) to two different arguments.  Consequently you have
two different results.  This is entirely referentially transparent!

When you expand the do syntax what you're writing is effectively

        getLine `bind` \ x ->
        getLine `bind` \ y ->
        ...

where the bind for IO could be defined to be similar to

        (f `bind` g) (s0,v0) = let (s1,v1) = f s0 in g v1 s1

That is the expression above is:

        let (s1,v1) = getLine s0 in
        let (s2,v2) = getLine s1 in
        ...

If you imagine the IO monad type to be defined something like:

        data IO a = IO ([String],a)

where a return replaces the "a" component and and <- applies the
function to the current value and the [String] component (the "state"),
and creates a new pair combining the resulting [String] state and
the IO result then

the do might be entered with the IO tuple               ([],())

the first getLine might create the new IO tuple         (["xline"],"xline")

the second getLine might create the new IO tuple
(["xline","yline"],"yline")

and "return x" would create the new IO tuple
(["xline","yline"],"xline")

etc.

In practice the list of strings can be simplified to
a single-threaded token representing the O/S state (and I
haven't explained lots of important details, which I'll leave
to others!).

Regards,
Kevin

----------
Division of Computer Science,               Tel: +44-1334 463241 (Direct)
School of Mathematical                      Fax: +44-1334 463278
 and Computational Sciences,                URL:
http://www.dcs.st-and.ac.uk/~kh/kh.html
University of St. Andrews, Fife, KY16 9SS.



Reply via email to