Adding an ignore function to Control.Monad

Michael Snoyman michael at
Wed Jun 10 12:56:27 EDT 2009


I also remember this post by Neil Mitchell which seems appropriate:
He also uses the name "ignore" for your function.


On Wed, Jun 10, 2009 at 7:53 PM, Gwern Branwen <gwern0 at> wrote:

> Hash: SHA512
> So while writing my wp-archivebot, I ran into the issue that forkIO
> requires IO () but returns IO ThreadId, and that many useful IO
> functions will return IO a instead of IO ().
> This forces some awkward contortions. Suppose I want to ping the
> WebCite website at a particular address, and this request makes
> WebCite archive a URL embedded in that address. Presumably I could
> venture into the depths of Network.HTTP to figure out how to ping an
> URL without also pulling down the server's HTML, but why do that when
> I already have obviously 'openURL :: String -> IO String'?  Much
> easier to do something like 'openURL "" ++ foo ++ "other
> stuff" '.
> But my bot needs to handle quite a few URLs; one at a time, what with
> all the waits and timeouts, isn't going to hack it. So for a given
> link, I forkIO the openURL request. But of course, forkIO demands IO
> (), so I toss in a '>> return ()'. Fair enough.
> So I examine the performance, and it's still too slow. Recent Changes
> has hundreds of different pages a minute. I'd better fork each page
> (and then fork for each link). But wait, all those forkIOs are
> returning IO ThreadIds, and my top-level forkIO call demands IO ()...
> So another >> return (). At this point, the code is starting to look
> pretty silly - something like '...stuff >> return ()) >> return ())'.
> So I see the repeated pattern, and by the rule of 3, factor it out to:
> - -- | Convenience function. 'forkIO' and 'forM_' demand return types of
> 'IO ()', but most interesting
> - -- IO functions don't return void. So one adds a call to 'return ()';
> this just factors it out.
> ignore ∷ (Monad m) ⇒  m a →  m ()
> ignore x = x >> return ()
> Not the most complex convenience function I've ever written, but not
> any simpler than, say Control.Monad.forever or for that matter, most
> of the stuff in Control.Monad.
> I'd think it'd be useful for more than just me. Agda is lousy with
> calls to '>> return ()'; and then there's ZMachine, arrayref, whim,
> the barracuda packages, binary, bnfc, buddha, bytestring, c2hs, cabal,
> chesslibrary, comas, conjure, curl, darcs, darcs-benchmark,
> dbus-haskell, ddc, dephd, derive, dhs, drift, easyvision, ehc,
> filestore, folkung, geni, geordi, gtk2hs, gnuplot, ginsu, halfs,
> happstack, haskeline, hback, hbeat... You get the picture.
> I realize the specific name of 'ignore' can be bikeshedded to death,
> but it's clear, it's short, Hoogle turns up one other function with
> ignore in its name (Distribution.ParseUtils ignoreUnrec), and it's
> been independently named 'ignore' by another Haskeller (lilac).
> Existing uses of the string 'ignore are rare - it's in a few places as
> a variable, cabal and cabal-install and ehc and tar have where
> definitions of an ignore, a test for directory defines an ignore and
> imports Control.Monad unqualified, fit defines an 'ignore' but doesn't
> seem to use it in any module that also imports Control.Monad
> unqualified, halipeto defines an ignore but doesn't import
> Control.Monad, shim/yi has a let definition of an ignore, yhc has a
> where definition of an ignore. And that's about it. One of directory's
> tests would break, and the rest might have an additional -Wall
> warning.
> - --
> gwern
> Version: GnuPG v1.4.9 (GNU/Linux)
> iEYEAREKAAYFAkov5Q0ACgkQvpDo5Pfl1oIsRQCghUqynThzcT+OYV1KaYJhGFhv
> 6yYAnjf7CVOm0+Fg1FBa9IpdVIrRpCZm
> =Cd8V
> _______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...

More information about the Libraries mailing list