[Haskell-cafe] Constraints on <$> vs <$!>

Kim-Ee Yeoh ky3 at atamo.com
Tue Aug 11 07:05:39 UTC 2015

On Tue, Aug 11, 2015 at 5:32 AM, Ben <hyarion at iinet.net.au> wrote:

> In particular, this version of <$!> wouldn't help with the lazy IO problem
> described in that stackoverflow question Christopher linked earlier.

We can say more.

The version of <$!> that the SO question author himself gives as a solution
to the lazy IO problem doesn't really work.

I'm referring to:

forceM :: Monad m => m a -> m a
forceM m = do v <- m; return $! v
(<$!>) :: Monad m => (a -> b) -> m a -> m b
f <$!> m = liftM f (forceM m)

and changing out <$> for <$!> in

getLines h = lines <$> hGetContents h

With the change, all of short files get read, thanks to file buffering.
Like the first 4K or so. Bad surprise when you try it with longer files.

There's a right path through lazy I/O and a wrong one. Rather than take the
wrong one, better the following instead:

main = mapM_ putStrLn =<< lines <$> readFile "test.txt"

But if withFile is absolutely needed (experts only):

main = withFile "test.txt" ReadMode getAndPutLines  where
   getAndPutLines :: Handle -> IO ()
   getAndPutLines h = mapM_ putStrLn =<< lines <$> hGetContents h

-- Kim-Ee
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150811/5ea1b209/attachment.html>

More information about the Haskell-Cafe mailing list