How to mix different infix binds in the same code

#1

For now, I am fixing the code to use some functions that don’t cause exceptions.
Before code was consisting of function compositions with Lwt.Infix.(>>=).
But now also some variables in the code return (string, [ ``Msg of string ]) Stdlib.result instead of string.
To avoid using pattern matching here, I want to use result binding too. Is there any way to do that?
E.g. in

Base64.decode x >>= fun x' -> (* here it should be result *)
Base64.decode y >>= fun y' -> (* here it should be result *)
some_processing x' y' bla foo >>= fun r -> (* Here it is a bind from Lwt *)
more_processing r bar >>= fun q -> (* Here it is a bind from Lwt *)
...

I am asking about best idiomatic OCaml ways to do this, not just every single way possible.

0 Likes

#2

Because the pattern of having a result inside a promise is so common (e.g. an HTTP request that might fail), Async provides a “Deferred.Result” monad where the type is a Result.t Deferred.t, with the associated infix operators and let-syntax. And if it’s awkward to open that module, then there are also infix bind and map operators >>=? and >>|? exposed in Async itself. So one option would be to implement the equivalent of those functions for Lwt, assuming they don’t exist already.

0 Likes

#3

Since you have result, and not Lwt_result, I think it’s impossible, unless you do

let (>>=) = Lwt.bind
and (>>=?) = Lwt_result.bind in
Lwt.return @@ Base64.decode x >>=? fun x' -> (* here it should be result *)
Lwt.return @@ Base64.decode y >>=? fun y' -> (* here it should be result *)
some_processing x' y' bla foo >>= fun r -> (* Here it is a bind from Lwt *)
more_processing r bar >>= fun q -> (* Here it is a bind from Lwt *)
...
Lwt.return_ok final_value
3 Likes

#4

I think this is the best solution I saw. With some internal beauty.

0 Likes