> IO is reflected in the type signature of Haskell functions.
What you mean is, "effects are reflected". Haskell has a monadic effect system (IO is very rough-grained part of it), which can be combined via monadic transformers.
Situations where you don't want to use OCaml:
- you need good parallelism and using multiple processes are not enough (concurrency is fine, though)
- you want a large pool of developers (also applies to Haskell, but less so)
- you like monadic effect systems
- you need a number of libraries which are not present in the OCaml ecosystem
- you want a build system that doesn't suck
- you want a good standard library
- you want typeclasses
Why you'd want to use OCaml over Haskell:
- fast compilation (especially if you compile to bytecode)
- no monadic effect system
- no awful, ridiculous record field name collisions (OCaml lets you have two distinct types with an "id" field, imagine that)
- best-in-class package manager
- faster than Haskell (I think?)
- eagerly evaluated (Haskell's informal motto is "if it compiles it works", complemented by "until you get a memory leak") and therefore makes it much easier to reason about performance
- high-quality ecosystem (though not always very well documented)
- labeled arguments (many Haskell libraries have these functions with lots of arguments which are quite confusing in the absence of labeled arguments)
- great support for Vim/Emacs (IMHO, the Haskell equivalent to Merlin/ocp-indent are not nearly as good, or at least were not as a few years ago)
- great REPL via utop (just don't use the standard one, it's terrible)
- an object system if you really need one
- functors
- pleasant "printf debugging" option, with a possibility of using a real debugger if you need