
On Sun, Oct 05, 2003 at 11:37:16AM +0200, Tomasz Zielonka wrote:
On Sun, Oct 05, 2003 at 04:25:41AM -0000, kuq32tr02@sneakemail.com wrote:
2. main = do text <- readFile "test" let something = somefunc text writeFile "test" $! something
Are both of these correct (guaranteed to give the behavior I want)? Which is better (and why)?
depends on your "somefunc" try: -------------------- somefunc = show . f . read where f :: (Show a, Read a, Num a) => [a] -> (a,a) f ls = (sum (take 3 ls), mul (take 3 ls)) mul :: (Num a) => [a] -> a mul = foldr (*) 1 --------------------- if somefunc read all the needed data before returning the result, then the program will either work correctly or give an exception. I think throwing an exception here is wrong. so: --------------- somefunc = (show . f . read) where f :: (Show a, Read a, Num a) => [a] -> (a,a) f ls = seq (ls!!2) (sum (take 3 ls), mul (take 3 ls)) --------------- must be OK.
There is no guarantee that $! will force evaluation of the entire 'something', so you can start writing to file before you finished reading from it. Hopefully it will cause an exception (like in GHC), otherwise you could damage your data (like in Hugs).
If "test" is not a regular file (say, "/dev/modem"), then it is 100% legal program. So throwing any exception here is not correct (I believe it is done by ghc runtime, since there is nothing exceptional in opening a file for writing already opened for reading, at least in Unix). Anyway such a "defence" will not work with concurrently running programs. -- Max