问题
Newbie question:
Say I have a function do_sth that is very slow, and it is applied to range 1 to n. I want to print the result of do_sth i when it is looping. How to do this? A naive attempt fails as the values will only be printed after the whole loop:
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
回答1:
Effects in Ocaml are eager by default: the language is said to have eager evaluation1, as opposed to so called lazy languages like Haskell.
The result you are witnessing is due to buffering done by output primitives for stdout. Simply flushing the buffers with Pervasives.flush stdout or Pervasives.flush_all () will provide the desired behaviour.
Also, you may optimise your function by making it tail recursive: instead of doing the sum after the recursive call, accumulate the result in a function parameter:
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) However Ocaml also supports lazy evaluation of some sort through the module Lazy, but evaluation has to be triggered explicitely in certain situations.
回答2:
How about you do the following instead :
let fi = do_sth i in
let () = Printf.printf "%d %d\n" i fi in
fi + loop (i+1)
来源:https://stackoverflow.com/questions/27731647/eager-side-effect-printf-in-ocaml