Why discarded values are () instead of ⊥ in Haskell?
haskell
Solution
I think this is because you need to specify the type of the value to be discarded. In Haskell-98, `()` is the obvious choice. And as long as you know the type is `()`, you may as well make the value `()` as well (presuming evaluation proceeds that far), just in case somebody tries to pattern-match on it or something. I think most programmers don't like introducing extra ⊥'s into code because it's just an extra trap to fall into. I certainly avoid it.
Instead of `()`, it is possible to create an uninhabited type (except by ⊥ of course).
{-# LANGUAGE EmptyDataDecls #-}
data Void
mapM_ :: (Monad m) => (a -> m b) -> [a] -> m Void
Now it's not even possible to pattern-match, because there's no `Void` constructor. I suspect the reason this isn't done more often is because it's not Haskell-98 compatible, as it requires the EmptyDataDecls extension.
Edit: you can't pattern-match on Void, but `seq` will ruin your day. Thanks to @sacundim for pointing this out.
Problem
Howcome in Haskell, when there is a value that would be discarded, `()` is used instead of `⊥`? Examples (can't really think of anything other than IO actions at the moment): ``` mapM_ :: (Monad m) => (a -> m b) -> [a] -> m () foldM_ :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m () writeFile :: FilePath -> String -> IO () ``` Under strict evaluation, this makes perfect sense, but in Haskell, it only makes the domain bigger. Perhaps there are "unused parameter" functions `d -> a` which are strict on `d` (where `d` is an unconstrained type parameter and does not appear free in `a`)? Ex: `seq`, `const' x y = y`seq`x`.