Take the 2-minute tour ×  I thought that in principle haskell's
type system would forbid to call impure functions (i.e. f :: a
-> IO b) from pure ones, but today I realized that by calling
them with return they compile just fine. In example:  h :: Maybe
() h = do     return $ putStrLn "???"     return ()  Now, h
works in the maybe monad, but it's a pure function nevertheless.
Compiling and running it simply returns Just () as one would
expect, without actually doing any I/O. I think haskell's
laziness puts the things together (i.e. putStrLn's return value
is not used - and can't since its value constructors are hidden
and I can't pattern match against it), but why is this code
legal? Are there any other reasons that makes this allowed?  As
a bonus, related question: in general, is it possible to forbid
at all the execution of actions of a monad from within other
ones? How?  share|improve this question add comment  2 Answers
up vote 18 down vote accepted  IO actions are first-class values
like any other; that