Is it ok to use Lwt.return as the final call in a recursive function?
I have a function that compiles fine but does not run properly and it looks like the function f
below. Please assume that there is no issue with any function provided as g
in this example, I am basically just trying to find out if it is ok to have a function with the following form or if there is a better/simpler (and Lwt compliant) way of doing the following:
let rec f (x : string list) (g : string -> unit Lwt.t) =
match List.length x with
| 0 -> Lwt.return ()
| _ -> g (List.hd x) >>= fun () -> f (List.tl x) g
;;
val f : string list -> (string -> unit Lwt.t) -> unit Lwt.t = <fun>
I am pretty sure that I am doing it wrong. But the actual function I am using is much more complex than this example so I am having a difficult time debugging it.
First of all the correct way of dealing with lists in OCaml is deconstructing them with pattern matching, like this:
let rec f (xs : string list) (g : string -> unit Lwt.t) =
match xs with
| [] -> return ()
| x :: xs -> g x >>= fun () -> f xs g
The next step would be notice, that you're actually just perform iteration over a list. There is a Lwt_list.iter_s
for this:
let f g xs = Lwt_list.iter_s g xs
That can simplified even more
let f = Lwt_list.iter_s
That means, that you even do not need to write such function, since it is already there.
And finally, there was no issues with recursion in your original implementation. The function that you've provided was tail recursive.