在 OCaml 中使用 Lwt 时如何中断循环
How to make a loop break when using Lwt in OCaml
我正在编写代码来监视文件的内容。当程序到达文件末尾时,我希望它干净地终止。
let log () : input_channel Lwt.t =
openfile "log" [O_RDONLY] 0 >>= fun fd ->
Lwt.return (of_fd input fd);;
let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text ->
Lwt_io.printl text >>= fun _ -> loop ic;;
let monitor () : unit Lwt.t = log () >>= loop;;
let handler : exn -> unit Lwt.t = fun e -> match e with
| End_of_file -> let (p: unit Lwt.t), r = Lwt.wait() in p
| x -> Lwt.fail x;;
let main () : unit Lwt.t = Lwt.catch monitor handler;;
let _ = Lwt_main.run (main ());;
但是,当读取文件并到达末尾时,程序并没有终止,它只是挂起,我必须使用 Ctrl+c 退出。我不确定 bind 背后发生了什么,但我想无论它在做什么,最终 Lwt_io.readline ic
最终应该到达文件末尾并且 return 一个 End_of_file
异常,大概会被传递给处理程序等。
如果我不得不猜测解决方案,我想也许在 >>=
定义的最后绑定中我会包含一些 if
检查。但我认为,我会检查 Lwt_io.read_line
return 是否编辑了 End_of_file
,我认为应该由 handler
处理。
Lwt.wait
函数创建了一个只能使用返回对的第二个元素来解决的承诺,基本上,这个函数永远不会终止:
let never_ready () =
let (p,_) = Lwt.wait in
p
这正是您所写的内容。
关于优雅终止,理想情况下,您应该在 loop
函数中执行此操作,以便您可以关闭通道并防止泄漏宝贵的资源,例如,
let rec loop (ic: input_channel) =
Lwt_io.read_line ic >>= function
| exception End_of_file ->
Lwt.close ic
| text->
Lwt_io.printl text >>= fun () ->
loop ic
但是,对代码的最小更改是在 handler
.
的正文中使用 Lwt.return ()
而不是 Lwt.wait
我正在编写代码来监视文件的内容。当程序到达文件末尾时,我希望它干净地终止。
let log () : input_channel Lwt.t =
openfile "log" [O_RDONLY] 0 >>= fun fd ->
Lwt.return (of_fd input fd);;
let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text ->
Lwt_io.printl text >>= fun _ -> loop ic;;
let monitor () : unit Lwt.t = log () >>= loop;;
let handler : exn -> unit Lwt.t = fun e -> match e with
| End_of_file -> let (p: unit Lwt.t), r = Lwt.wait() in p
| x -> Lwt.fail x;;
let main () : unit Lwt.t = Lwt.catch monitor handler;;
let _ = Lwt_main.run (main ());;
但是,当读取文件并到达末尾时,程序并没有终止,它只是挂起,我必须使用 Ctrl+c 退出。我不确定 bind 背后发生了什么,但我想无论它在做什么,最终 Lwt_io.readline ic
最终应该到达文件末尾并且 return 一个 End_of_file
异常,大概会被传递给处理程序等。
如果我不得不猜测解决方案,我想也许在 >>=
定义的最后绑定中我会包含一些 if
检查。但我认为,我会检查 Lwt_io.read_line
return 是否编辑了 End_of_file
,我认为应该由 handler
处理。
Lwt.wait
函数创建了一个只能使用返回对的第二个元素来解决的承诺,基本上,这个函数永远不会终止:
let never_ready () =
let (p,_) = Lwt.wait in
p
这正是您所写的内容。
关于优雅终止,理想情况下,您应该在 loop
函数中执行此操作,以便您可以关闭通道并防止泄漏宝贵的资源,例如,
let rec loop (ic: input_channel) =
Lwt_io.read_line ic >>= function
| exception End_of_file ->
Lwt.close ic
| text->
Lwt_io.printl text >>= fun () ->
loop ic
但是,对代码的最小更改是在 handler
.
Lwt.return ()
而不是 Lwt.wait