Some informal benchmarks suggest it's better to traverse by folding up something like
newtype STA a = STA (forall s. MutableArray# s a -> ST s (Array a))
in the functor, and then mapping over to initialize. Also, traversing in PrimBase functors is much more direct. It might be worth adding rewrite rules rewriting traverse in ST and IO to the special forms they support.