[Haskell-cafe] What is the consensus about -fwarn-unused-do-bind ?

Neil Brown nccb2 at kent.ac.uk
Fri Apr 9 10:20:34 EDT 2010


Ivan Lazar Miljenovic wrote:
> As of 6.12.1, the new -fwarn-unused-do-bind warning is activated with
> -Wall.  This is based off a bug report by Neil Mitchell:
> http://hackage.haskell.org/trac/ghc/ticket/3263 .
>
> However, does it make sense for this to be turned on with -Wall?  For
> starters, why should this warning apply only to do blocks and not to
> explicit usage of >>, etc.?  That is, the following code (as specified
> in the above bug report) generates an error:
>
>    do doesFileExist "foo"
>       return 1
>
> yet this doesn't:
>
>     doesFileExist "foo" >> return 1
>   
The comments in that bug report actually mention "My patch does not warn 
on uses of >>, only in do-notation, where the situation is more clear 
cut".  I take >> to be an explicit sign that the user wants to ignore 
the result of the first action, whereas in do-notation it may be an 
accident.  So I think it was the right decision.

When I first compiled my CHP library with it, I was surprised to find 
that I had very few instances: 6 warnings in ~3000 lines of 
heavily-monadic code.  And one or two of those I probably shouldn't be 
ignoring the return.

> The way I see it, I have 4 options:
>
>   1. Do as the error suggests and preface usage of these parser
>      combinators with "_ <-".
>
>   2. Use some function of type "(Monad m) => m a -> m ()" instead of doing
>      "_ <-".
>
>   3. Duplicate the parser combinators in question so that I have one
>      version that returns a value and another that does the main parser
>      and then returns (); then use this second combinator in do blocks
>      where I don't care about the returned value.
>
>   4. Put "-fno-warn-unused-do-bind" in the .cabal file.
>
> The first two options don't appeal to me as being excessive usage of
> boilerplate; the third involves too much code duplication.  However, I
> am loath to just go and disable a warning globally.
>   
I'd be tempted by number two, but I it's more typing to write "ignore $" 
than "_ <-", so maybe 1 is the best option after all.  I've frequently 
encountered the annoyance of monadic return values -- but to satisfy 
type signatures rather than avoid this warning.  For example, I have a 
CHP parallel operator: (<||>) :: CHP a -> CHP b -> CHP (a,b) and a 
function writeChannel :: Chanout a -> a -> CHP ().  But if you try to 
write a function like:

writeBoth :: a -> (Chanout a, Chanout a) -> CHP ()
writeBoth x (outA, outB) = writeChannel outA x <||> writeChannel outB x

You get a type error (expected: CHP (), but got: CHP ((), ()) -- both 
return types contain no information anyway!).  You either have to append 
">> return ()" (or similarly use do-notation), or do as I did and make 
another form of the operator that discards the output (and there I can't 
use the add-another-underscore convention!).

It's annoying that you end up with lots of operations in libraries 
duplicated with an underscore variant, or different operators.  
Sometimes it can make an important semantic difference (e.g. mapM 
requires Traversable but mapM_ only requires Foldable), but often it's 
just a matter of "no, I don't care about the return value from this" 
(e.g. forkIO).  I sometimes wonder if there could be some syntactic 
sugar that might help, but it does feel like overkill just for this purpose.

Thanks,

Neil.


More information about the Haskell-Cafe mailing list