haskell-issues icon indicating copy to clipboard operation
haskell-issues copied to clipboard

forever :: m () -> m Void; (>>) :: m () -> m a -> m a

Open Gurkenglas opened this issue 8 years ago • 3 comments

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?)

Gurkenglas avatar Mar 19 '16 19:03 Gurkenglas

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.

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!).

neongreen avatar Mar 19 '16 21:03 neongreen

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 ()

Gurkenglas avatar Mar 26 '16 11:03 Gurkenglas

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).

neongreen avatar Mar 31 '16 23:03 neongreen