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

moving to libraries@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.

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 ().
Haskell doesn't have subtyping, so this wouldn't really make sense. Perhaps a typeclass Top would make sense (where the compiler automatically creates an instance of it for all types), but then `Top a => a` would be equivalent to just `a`, so it wouldn't really serve any purpose.
participants (2)
-
Dan Burton
-
Henning Thielemann