Talk:IO inside
From HaskellWiki
| Line 104: | Line 104: | ||
(answer, world2) = get2chars world1 | (answer, world2) = get2chars world1 | ||
in ((), world2) | in ((), world2) | ||
| + | |||
| + | Section added by [[User:Billshewman|Billshewman]] 5 April 2011 | ||
Revision as of 13:53, 5 April 2011
Hi,
I just stumbled over this IO tutorial, and gave it a quick glance for
the usual issues. Unfortunately, it seems to propagate a seriously
misleading picture of the IO type:
IO cannot, must not be a type synonym. As long as Haskell does not
have a uniqueness type system, any functional representation of IO
must be hidden behind an abstract type!
making only RealWorld abstract is insufficient, as functional programming
would still allow us to create RealWorlds out of thin air, or let them
disappear:
oops :: RealWorld -> (Char,RealWorld)
oops rw = let (c1,rw1) = getChar rw
(c2,rw2) = getChar rw
in ([c2,c1],rw1)
whoCares rw = (rw,rw) -- let's make a copy while we're at it
fortunately, the fix is simple (but crucial):
- make IO a newtype
- do handle code inside the abstract type with great care,
as many functional equivalences are no longer valid!
actually, only the first part is simple, the second part
depends on some apparently and happily valid properties of
typical optimizations in the implementations.
keeping IO abstract also makes it clear that other implementations
are possible, and have been used (such as having an interpretation
loop for the tree of i/o operations computed by main).
also, it might be more useful to think of unsafePerformIO
linking into the implicit RealWorld at its point of evaluation,
rather than creating an all new one to throw away. this
linking in is what makes it so useful as an extension hook
for the Haskell implementation.
inlinePerformIO: Don, i've reverted its "definition" to pseudo-form because
if we consider this as step-by-step tutorial, at this point reader
is yet not know about GHC specific of IO type representation. my definition
just duplicates pseudo-definitoon of unsafePerformIO in previous section
adding only INLINE instruction. otherwise, reader may be lost in these "differences"
between two definitions and GHC-specific details Bulatz 15:47, 18 March 2007 (UTC)
1 when definition wrong
The definition for when
when :: Bool -> IO () -> IO () when condition action world =
does not compile. The compiler says The equation(s) for `when' have three arguments, but its type `Bool -> IO () -> IO ()' has only two. I cannot fix it, I don't understand it (yet). Franky 15:53, 17 January 2011 (UTC)
2 The first examples of 6.0 don't work
The first examples of section 6.0 actually prove the opposite of what you are trying to say. The expressions seem to get executed out of the desired order. I've compiled this program on both Windows and Mac.
main = do let get2chars = getChar >> getChar
putStr "Press two keys"
get2chars
return ()
It doesn't print anything until after you hit enter. And then it exits. I tried to compile this version on a Mac and Windows and it doesn't even compile:
main world0 = let get2chars = getChar >> getChar
((), world1) = putStr "Press two keys" world0
(answer, world2) = get2chars world1
in ((), world2)
The output of the compiler is
C:\Users\cwelchmi>ghc getChar2.hs [1 of 1] Compiling Main ( getChar2.hs, getChar2.o )
getChar2.hs:1:1:
Couldn't match expected type `IO t0'
with actual type `t1 -> ((), t2)'
In the expression: main
When checking the type of the function `main'
getChar2.hs:2:34:
The function `putStr' is applied to two arguments,
but its type `String -> IO ()' has only one
In the expression: putStr "Press two keys" world0
In a pattern binding: ((), world1) = putStr "Press two keys" world0
In the expression:
let
get2chars = getChar >> getChar
((), world1) = putStr "Press two keys" world0
(answer, world2) = get2chars world1
in ((), world2)
getChar2.hs:3:38:
The function `get2chars' is applied to one argument,
but its type `IO Char' has none
In the expression: get2chars world1
In a pattern binding: (answer, world2) = get2chars world1
In the expression:
let
get2chars = getChar >> getChar
((), world1) = putStr "Press two keys" world0
(answer, world2) = get2chars world1
in ((), world2)
Section added by Billshewman 5 April 2011
