新手问题:
假设我有一个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
Run Code Online (Sandbox Code Playgroud)
默认情况下,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
Run Code Online (Sandbox Code Playgroud)
(1)但是Ocaml还支持通过模块进行某种形式的延迟评估Lazy,但是评估必须在某些情况下明确触发。