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