&gt; But it does because their type says so:<p>Sure. But I remember doing this with checked exceptions, mousing over each method call one by one to figure out which ones could or couldn&#x27;t throw. It&#x27;s much nicer if you can see which methods are the throwey ones immediately - =&#x2F;&lt;- is a real sweet spot in terms of having the difference be visible but not overly intrusive.<p>&gt; But that&#x27;s the opposite of a problem. That&#x27;s like using `IO a` outside of an IO monad. You want the function to only be called in the right context (an appropriate handler is in effect).<p>Disagree. I want to be able to have a value of type IO a outside a method - e.g. in a static field. More generally it&#x27;s really huge to be able to just treat these things as ordinary values that I can manipulate using the ordinary rules of the language.<p>&gt; I&#x27;m not sure if the same effects would make sense, though. For example, Either is a monadic value which doesn&#x27;t make sense in an imperative setting.<p>The two effects are &quot;possibly skip the rest of the computation, returning an Error instead&quot; and &quot;record a programatically-accessible Log&quot; - I think those both make sense. The point is the reason you have to use the horrible monad transformers is that the order in which you evaluate these effects matters - if there&#x27;s an early error, are later log statements recorded, or not? There are more complicated cases when e.g. catching I&#x2F;O errors.