I tend to think of OCaml as a functional C. It's strict and not purely functional. You can write for-loops and while-loops if you want (but you shouldn't) and use refs to have mutable state (but you shouldn't). It has a better module system than Haskell, but doesn't have type classes. It has functors, which are equivalent-- OCaml's functor is an operation over modules and only very loosely connected (through type theory, which isn't essential to being proficient in either language) to Haskell's Functor type class-- and better in some ways and worse in others.
Haskell is more expressive and has a much more powerful type system, but it's probably harder to reason about performance.
OCaml's biggest issue (note: I may be out of date on this, since I haven't heavily used it since the late 2000s) is the GIL. This probably limits your ability to use it for multithreaded programming, but it can compile down to extremely fast single-threaded executables.
Can you compare that to Scala? Scala also has non-pure constructs built in, but most people tend to opt in to its purity. And I don't know much about OCaml, but it seems like Scala may have better type system parity with Haskell's type level features.
Haskell is more expressive and has a much more powerful type system, but it's probably harder to reason about performance.
OCaml's biggest issue (note: I may be out of date on this, since I haven't heavily used it since the late 2000s) is the GIL. This probably limits your ability to use it for multithreaded programming, but it can compile down to extremely fast single-threaded executables.