[Haskell] Types of when and unless in Control.Monad

Henning Thielemann lemming at henning-thielemann.de
Sat Apr 21 12:45:43 CEST 2012

moving to libraries at haskell.org ...

Andreas Abel schrieb:
> In Control.Monad, when has type
>   when :: Monad m => Bool -> m () -> m ()
> I think this type should be generalized to
>   when :: Monad m => Bool -> m a -> m ()
> to avoid silly "return ()" statements like in
>   when cond $ do
>     monadicComputationWhoseResultIWantToDiscard
>     return ()

You may use the new 'void' function for that purpose.

Generally I prefer to not ignore monadic results by default. I also do
not like that behavior in the C programming language. GHC now warns
about unused non-() results in a do-block. But (>>) and mapM_ still
ignore non-unit results of monadic action, and certainly have to remain
this way because of Haskell-98 compatibility.

If a monadic action has a result, then this has a reason. If I have to
apply a 'void' then I think about whether it is correct to ignore the
result. E.g. if the result is an ExitCode then it may be convenient to
ignore it (like in C), but it is certainly not correct to do so.

It was often stated that for parsers ignoring of the parsed results by
default is a good idea. However since GHC warns about implicitly ignored
monadic results in do-notation, I found that many warnings in parsers
are due to not using the right parser combinators. E.g. I often found
something like

  do char '('
     x <- expression
     char ')'
     return x

and this should certainly be rewritten to
  between (char '(') (char ')') expression

That is, those warnings about implicitly ignored results helped me to
improve my code.

> P.S.:  A more systematic solution would be to change the Haskell
> language by either introducing a Top type which is the supertype of
> everything and use it instead of ().

There is the type Any, but I suspect it cannot be written in source
code. But I think a type variable like 'a' is the right thing to use.

More information about the Libraries mailing list