1. modularity (and now that they have added generative functors à la SML, you can have true abstraction)
2. benign effects: in Haskell "proper", you do not have effects; rather you have "codes" for effects, which get interpreted into effects by the RTS; this rules out the possibility of, e.g., using effects to implement a semantically pure interface. On the other hand, OCaml has actual effects, which can be used in an open-ended way to implement all sorts of functional interfaces.
3. strictness: arguments abound about whether laziness or strictness is better; for me, it comes down to the fact that with some pain, you can embed laziness in a strict language with effects, but you cannot embed full-on ML-style strictness into a language like Haskell; moreover, strictness-by-default permits safe uses of benign effects.
I'd call Haskell an expression-oriented programming language, since the types end up classifying expressions and algorithms (i.e. the particular "effects" you used get put into the type). Whereas I'd say (OCa)ML is a value-oriented language, since values (canonical forms) are considered separately from general expressions (canonical and non-canonical forms); moreover, implementation details don't end up in the types, so you can really consider them to be classifying values and functions (i.e. equivalence classes of algorithms, not algorithms themselves). This is largely orthogonal from strictness vs laziness, but as soon as you add partiality in, strictness becomes the only tractable way to have canonical-form-based meaning explanations for the judgements of the theory.
P.S. My day job is writing Haskell. (In case the Pedagogical Brethren wish to come and "correct" me.)