You&#x27;re right, but ST is also implemented using unsafePerformIO.  The larger point is that you don&#x27;t need to dress up a type signature with ST or IO just to use imperative code internally which can&#x27;t leak out to the user level.  Whether this is good or bad is a matter for debate, but used judiciously I think it&#x27;s good.