Haskell was designed for theory. SML was designed to combine being pragmatic and easy to teach (not only the language, but how to implement). Other than syntax, SML's fundamental nature is much closer to Rust (with a GC and simpler syntax and without lifetimes, macros, or traits).
In any case, let's look at those haskell "hard parts" and contrast them.
Haskell treats everything as immutable. SML is NOT always immutable. It simply adds some (very sane) constraints on where mutation can occur which makes reasoning about mutation easier.
Haskell forbids side effects. This is an illusion of course (you'll find high-performance libraries often use the unsafe IO stuff). SML embraces side effects though general practice is to restrict them to specific modules to make the program easier to reason about (a good practice in pretty much all languages). You can definitely write imperative pieces of code if it improves performance.
Haskell is lazily evaluated. This can be a performance boon for some things, but is a bane to find and fixing performance bottlenecks. SML is eagerly evaluated like most other languages.
Haskell is crazy for typeclasses. They use them everywhere, but they often complicate actually using things. SML does not have type classes, but SucessorML (the next version) is looking at adding module typeclasses instead. These will have most of the same features, but because they are in the module instead, it should put a big limit on their abuse and make their use easier to track.
SML's big "ivory tower" ideas are: powerful type system, pattern matching, option types everywhere, first-class functions, and modules (essentially as a replacement for classes though that is not entirely true).
SML really is the whole package. The best parts of functional programming combined with the best parts of mainstream languages (restricted to the "good" subset) all tied up in a language definition that manages to reduce the amount of syntax compared to something like Java or Go while increasing the amount of power while at the same time not turning into an unreadable mess (it's pretty hard to write unreadable SML code).