haskell-issues
haskell-issues copied to clipboard
forever :: m () -> m Void; (>>) :: m () -> m a -> m a
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 the Int
implicitly, this should be made explicit via void :: m a -> m ()
. The ()
is conjured from nothing (or rather, from Void
), because forever
does not ever return a value. Using its output value is absurd and thus should be made explicit via fmap 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
with a
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 by forkIO
. (And thus, there should be forkIO_
. Hmm. Does this belong in a new issue?)
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
andsatisfy :: (Char -> Bool) -> Parser Char
(very often) -
takeMVar :: MVar a -> IO a
when used to empty theMVar
-
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:
- mapM_ :: (Monad m, Foldable t) => (a -> m ()) -> t a -> m ()
- traverse_ :: (Applicative f, Foldable t) => (a -> f ()) -> t a -> f ()
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).