I'd say STM can't do it, and it's on purpose. A piece of STM code can be restarted multiple times at various places if a transaction rolls back. What would happen if you run your transaction, it performs the I/O action and then rolls back when recording the results in the variables?
For this reason STM computations must be pure, only with the addition of STM primitives such as STM mutable variables and arrays.