首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lwt与递归函数

Lwt与递归函数
EN

Stack Overflow用户
提问于 2015-04-07 01:07:42
回答 2查看 465关注 0票数 0

使用Lwt.return作为递归函数中的最后调用可以吗?

我有一个编译得很好但不能正常运行的函数,它看起来像下面的函数f。请假定在本例中提供的任何函数都没有问题,我基本上只是想了解是否可以使用以下形式的函数,或者是否有一种更好/更简单(且兼容g )的方法来执行以下操作:

代码语言:javascript
复制
 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>  

我很肯定我做错了。但是我所使用的实际函数比这个例子要复杂得多,所以我很难调试它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-07 02:14:48

首先,在OCaml中处理列表的正确方法是使用模式匹配来解构它们,如下所示:

代码语言:javascript
复制
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用于此:

代码语言:javascript
复制
let f g xs = Lwt_list.iter_s g xs

可以简化得更多

代码语言:javascript
复制
let f = Lwt_list.iter_s

这意味着,您甚至不需要编写这样的函数,因为它已经存在了。

最后,在最初的实现中没有递归问题。您提供的函数是尾递归的。

票数 6
EN

Stack Overflow用户

发布于 2015-04-07 16:48:21

这取决于g是否返回已经计算过的lwt线程,如return ()或调度,并在稍后由lwt调度程序唤醒。在前一种情况下,对fun () -> f (List.tl x) g的调用可能是立即进行的,而不是稍后计划的,这可能会根据正在进行的优化来扩展堆栈。

我认为您的代码不应该依赖于如此棘手的行为。对于这个特殊的例子,正如@ivg的答案中所建议的那样,您应该使用来自Lwt_list模块的函数。

看看Lwt_list模块的实现是个好主意,看看它是如何实现的。同样的建议也适用于OCaml标准库。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29482085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档