Open Gurkenglas opened 8 years ago
This would also imply that do notation would complain if you insert lines of type
m a
witha
not being()
without binding them to something.
Well, GHC already has this as a warning (which becomes an error with -Wall
).
When would you ever want to not bind them to something, anyway? I can only think of not needing the thread id returned by
forkIO
.
I can also think of:
char :: Char -> Parser Char
and satisfy :: (Char -> Bool) -> Parser Char
(very often)takeMVar :: MVar a -> IO a
when used to empty the MVar
getLine :: IO String
when it's used to implement something simple like “press Enter to continue”There are some cases where -implicitly throwing information away- hurts performance, tho: _ <- mapM
is slower than mapM_
; in such cases forbidding implicit throwing-away would be nice. Otherwise, I don't remember having been ever bitten by this (and so I always turn the -fwarn-unused-do-bind
flag off), and I like return values that I can optionally use (my argument for them is the same as my argument for optional parameters in other languages).
I remember that there were several discussions on mailing lists about changing the type of >>
, but I can't find them right now (if you can, please post them!).
Yea, those all sound like they ought to be made explicit with or void, although I'm not sure about char/satisfy. The mapM reminds me:
A-a-and a discussion about changing the type of forM_
has been started on the libraries mailing list: https://mail.haskell.org/pipermail/libraries/2016-March/026860.html (not by me, but still).
It should be made clear when information is thrown away, for the benefit of the writer, reader and automatic code makers like exference.
forever :: IO Int -> IO ()
discards theInt
implicitly, this should be made explicit viavoid :: m a -> m ()
. The()
is conjured from nothing (or rather, fromVoid
), becauseforever
does not ever return a value. Using its output value is absurd and thus should be made explicit viafmap absurd :: m Void -> m ()
.The second suggestion might be more controversion, but is made in the same vein. This would also imply that do notation would complain if you insert lines of type
m a
witha
not being()
without binding them to something. When would you ever want to not bind them to something, anyway? I can only think of not needing the thread id returned byforkIO
. (And thus, there should beforkIO_
. Hmm. Does this belong in a new issue?)