Yep, this is a hard problem. I wasn't super enthusiastic about the verbosity of option types when I first started programming OCaml, but almost two years later I'm quite convinced that they're the right way to do things. I really don't think there's a whole lot of downside, and being able to basically just not think about a large and hard-to-identify class of bugs is incredibly freeing.
This may not cover your use cases, but for cascading errors you can often write code something like the following:
match
foo_err ()
>>=? bar_err
>>=? baz_err
[... etc ...]
with
| Error e -> Log.error e
| Ok result ->
[...]
This ends up working pretty well when you're working with pure functions because there's not anything to unwind, but you're right that it doesn't solve all problems.If you're interested in talking to more people about this kind of thing, the Core mailing list might be a good place to try: https://groups.google.com/forum/?fromgroups#!forum/ocaml-cor...