
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@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe