Lwt 和递归函数
Lwt and recursive functions
可以使用 Lwt.return 作为递归函数的最终调用吗?
我有一个函数可以正常编译,但没有 运行 正确,它看起来像下面的函数 f
。请假设在这个例子中作为 g
提供的任何函数都没有问题,我基本上只是想知道是否可以使用以下形式的函数或者是否有 better/simpler(和 Lwt 兼容)执行以下操作的方式:
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>
我很确定我做错了。但是我使用的实际功能比这个例子复杂得多,所以我很难调试它。
首先,在 OCaml 中处理列表的正确方法是使用模式匹配解构它们,如下所示:
let rec f (xs : string list) (g : string -> unit Lwt.t) =
match xs with
| [] -> return ()
| x :: xs -> g x >>= fun () -> f xs g
下一步会注意到,您实际上只是对列表执行迭代。为此有一个Lwt_list.iter_s
:
let f g xs = Lwt_list.iter_s g xs
那还可以进一步简化
let f = Lwt_list.iter_s
也就是说,你甚至不需要写这样的函数,因为它已经存在了。
最后,您的原始实现中没有递归问题。您提供的函数是尾递归的。
这取决于 g
returns 一个 lwt 线程是否已被计算,例如 return ()
或被 lwt 调度程序调度并稍后唤醒。在前一种情况下,可能会立即调用 fun () -> f (List.tl x) g
而不是安排在以后调用,这可能会根据正在发生的优化来增加堆栈。
我认为您的代码不应该依赖于这种棘手的行为。对于这个特定示例,正如@ivg 的回答中所建议的那样,您应该使用 Lwt_list
模块中的函数。
最好查看 Lwt_list
模块的实现以了解它是如何完成的。同样的建议也适用于 OCaml 标准库。
可以使用 Lwt.return 作为递归函数的最终调用吗?
我有一个函数可以正常编译,但没有 运行 正确,它看起来像下面的函数 f
。请假设在这个例子中作为 g
提供的任何函数都没有问题,我基本上只是想知道是否可以使用以下形式的函数或者是否有 better/simpler(和 Lwt 兼容)执行以下操作的方式:
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>
我很确定我做错了。但是我使用的实际功能比这个例子复杂得多,所以我很难调试它。
首先,在 OCaml 中处理列表的正确方法是使用模式匹配解构它们,如下所示:
let rec f (xs : string list) (g : string -> unit Lwt.t) =
match xs with
| [] -> return ()
| x :: xs -> g x >>= fun () -> f xs g
下一步会注意到,您实际上只是对列表执行迭代。为此有一个Lwt_list.iter_s
:
let f g xs = Lwt_list.iter_s g xs
那还可以进一步简化
let f = Lwt_list.iter_s
也就是说,你甚至不需要写这样的函数,因为它已经存在了。
最后,您的原始实现中没有递归问题。您提供的函数是尾递归的。
这取决于 g
returns 一个 lwt 线程是否已被计算,例如 return ()
或被 lwt 调度程序调度并稍后唤醒。在前一种情况下,可能会立即调用 fun () -> f (List.tl x) g
而不是安排在以后调用,这可能会根据正在发生的优化来增加堆栈。
我认为您的代码不应该依赖于这种棘手的行为。对于这个特定示例,正如@ivg 的回答中所建议的那样,您应该使用 Lwt_list
模块中的函数。
最好查看 Lwt_list
模块的实现以了解它是如何完成的。同样的建议也适用于 OCaml 标准库。