ocamltail-recursionocsigenocaml-lwt

Lwt and recursive functions


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.


Solution

  • 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.