On Thu, Oct 18, 2007 at 22:58:48 +1000, Matthew Brecknell wrote:
>Magnus Therning:
>> Still no cigar :(
>>Yes, this is a little more subtle than I first thought. Look at liftM
>and filterM:
>>liftM f m1 = do { x1 <- m1; return (f x1) }
>>filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
>filterM _ [] = return []
>filterM p (x:xs) = do
> flg <- p x
> ys <- filterM p xs
> return (if flg then x:ys else ys)
>>In liftM, the result of (f x1) is not forced, and in filterM, flg is
>not tested until after xs is traversed. The result is that when filterM
>runs the (p x) action, a file is opened, but hasEmpty (and thus
>readFile) is not forced until all other files have likewise been
>opened.
>>It should suffice to use a more strict version of liftM:
>>liftM' f m1 = do { x1 <- m1; return $! f x1 }
>>That should also fix the problem with Jules' solution, or alternatively:
>>readFile' f = do s <- readFile f
> return $! (length s `seq` s)
Another question that came up when talking to a (much more clever)
colleague was whether the introduction of either of the solutions in
fact means that only a single file is open at any time?
/M
(I really miss IRC connectivity at work at times like this. :-)
--
Magnus Therning (OpenPGP: 0xAB4DFBA4)
magnus＠therning．org Jabber: magnus．therning＠gmail．com
http://therning.org/magnus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20071018/dbcb2fd2/attachment.bin