runSTE is the workhorse of the STE monad. Runs an STE computation, and
also does the toplevel handling of the abortive throwSTE operator.
The naive way to handle errors is to simply write handleSTEid md.
runSTE does not and cannot (by design) handle pure or async exceptions.
throwSTE is the STE sibling of throwIO, and its argument
must match the e parameter in STE e s a. There is also no Exception e
constraint.
throwSTE should be thought of as an "abort" operation which is guaranteed to be
caught/handled by runSTE.