新手问题:
假设我的函数do_sth
非常慢,并且它适用于范围1到n。我想在循环时打印do_sth i
的结果。这该怎么做?一个天真的尝试失败,因为这些值只会在整个循环之后打印出来:
let rec loop i =
if i>1000 then 0
else
let fi = do_sth i in
(
Printf.printf "%d %d\n" i fi;
fi + loop (i+1)
)
let f_sum = loop 1
答案 0 :(得分:5)
默认情况下,Ocaml 中的效果非常渴望:据说该语言具有急切的评估 1 ,而不是像 Haskell
您目击的结果是由stdout
的输出原语完成的缓冲。只需使用Pervasives.flush stdout
或Pervasives.flush_all ()
刷新缓冲区即可提供所需的行为。
此外,您可以通过使尾部递归来优化您的函数:在递归调用之后不是执行求和,而是将结果累积到函数参数中:
let loop i =
let rec loop r i =
if i>1000 then r
else
let fi = do_sth i in (
Printf.printf "%d %d\n" i fi;
flush stdout;
loop (r+fi) (i+1)
)
in loop 0 i
(1)然而,Ocaml还支持通过模块Lazy
进行某种延迟评估,但在某些情况下必须明确触发评估。
答案 1 :(得分:0)
你如何做以下事情:
let fi = do_sth i in
let () = Printf.printf "%d %d\n" i fi in
fi + loop (i+1)