In other languages, I prefer to arrange source files so that simpler and more widely useful concepts are introduced before implementation details, and I try where possible to make complex implementation details top-level functions so that I can separate them out and let the main function read like a high-level algorithm description.
OCaml obviously has an interface/source distinction, but even with a sparse well-documented interface like
type t (** Blah blah blah *) val important_operator : t -> t -> t (** Blah blah blah *)
I've been tempted to do things like
let rec important_operator a b = let a', b' = foo a b in let a', b' = iterate_until_convergence (=) (fun (a, b) -> bar (baz a b)) (a', b') in merge a', b' (* Implementation details *) and foo a b = ... and bar x = ... and baz a b = ... and merge a b = ...
Is this poor style? Does it affect the ability of IDE-users to navigate source files?