[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