[Haskell-cafe] Newbie and working with IO Int and Int

Daniel Fischer daniel.is.fischer at web.de
Tue Oct 17 15:00:13 EDT 2006


Am Dienstag, 17. Oktober 2006 19:37 schrieb Víctor A. Rodríguez:
> > What's wrong with doing it this way?
> >
> > -- ** UNTESTED CODE **
> >
> > verifyAdd :: Int -> Int -> Int -> Bool
> > verifyAdd a b sum | a + b == sum = True
> > otherwise = False
> >
> > testAddMundane :: Int -> Int -> Bool
> > testAddMundane a b = verifyAdd a b (a + b)
> >
> > -- all the IO-dependent stuff is below this line --
> >
> > testAddRandom :: IO Bool
> > testAddRandom = do a <- randomIO
> > b <- randomIO
> > return verifyAdd a b (a + b)
>
> I discovered something worst yet :-P
> Using the next code and calling verifyAdd or testAddMundane it says :
>
> Program error: verifyAdd: ERROR
>
> Instead calling testAddRandom only says :
> :: IO Bool
>
> (55 reductions, 92 cells)

Well, that's absolutely correct.
'return (error "ERROR")' is different from  'error "ERROR"' and is a perfectly 
well-behaved monadic value.
As long as you don't try to evaluate the returned value (e.g. for printing 
it), it doesn't trigger the error (remember, Haskell is lazy!). And by 
default, hugs doesn't print the results of IO-actions:
Hugs> putStrLn "No result"
No result

Hugs> :set +I
Hugs> putStrLn "No result"
No result
()          <- this is the result of the IO-action putStrLn "No Result"

The option +I says you want the results of IO-actions to be printed, and 
indeed:

Verify> :set +I
Verify> testAddRandom

Program error: verifyAdd: ERROR

The same, if we explicitly ask for the result to be printed if the +I option 
isn't set:
Verify> testAddRandom >>= print

Program error: verifyAdd: ERROR


ghci-6.6 does so by default (for some IO-actions, not for e.g. putStrLn ".."):
*Verify> testAddRandom
*** Exception: verifyAdd: ERROR
Prelude System.CPUTime> t <- getCPUTime
130000000000


and ghci-6.4.2 like hugs needs to be asked for the result of the IO-action
*Verify> r <- testAddRandom
*Verify> r
*** Exception: verifyAdd: ERROR
*Verify> testAddRandom
*Verify> it
*** Exception: verifyAdd: ERROR

Now let's use the result of testAddRandom:

testAnew :: IO ()
testAnew = do b <- testAddRandom
              print (True || b)
              print (False && b)
              print b

b is bound to the result of testAddRandom, i.e. error "verifyAdd: ERROR",
but it is not evaluated until needed, so True and False get printed before the 
exception is raised when we ask for it to be printed.

*Verify> testAnew
True
False
*** Exception: verifyAdd: ERROR

HTH,
Daniel
>
> ---- CODE STARTS HERE, AND IS TESTED -----
>
> import Random
>
> verifyAdd :: Int -> Int -> Int -> Bool
> verifyAdd a b sum = error "verifyAdd: ERROR"
>
> testAddMundane :: Int -> Int -> Bool
> testAddMundane a b = verifyAdd a b (a + b)
>
> -- all the IO-dependent stuff is below this line --
>
> testAddRandom :: IO Bool
> testAddRandom = do a <- randomIO
> b <- randomIO
> return ( verifyAdd a b (a+b) )
>
> --
> Víctor A. Rodríguez (http://www.bit-man.com.ar)
> El bit Fantasma (Bit-Man)
> Perl Mongers Capital Federal (http://cafe.pm.org/)
> GNU/Linux User Group - FCEyN - UBA (http://glugcen.dc.uba.ar/)
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list