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.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to