OCaml Printf.printf - 缺少输出之谜

时间:2014-07-15 11:50:21

标签: ocaml

以下代码......

type 'a osResult =
  Success of 'a
| Error of string


let errorCatcher f =
  try
    let result = f () in
    Success result
  with Unix.Unix_error (code, fun_name, arg) ->
    Error(String.concat ":" [(Unix.error_message code); fun_name; arg])

let my_getcwd () = 
  errorCatcher (fun () -> Unix.getcwd ())

let _ =
  print_endline "The Start";
  let result = my_getcwd () |> function
  | Success folder -> Printf.sprintf "getcwd:\n\t%s\n" folder
  | Error errMessage -> Printf.sprintf "getcwd (error):\n\t%s\n" errMessage
  in
  print_string result ;
  print_endline "The End."
;;

...编译好:

$ corebuild -tag debug test1.native

......运行良好:

$ ./test1.native 
The Start
getcwd:
        /home/ttsiod/work/byePythonHelloOCaml
The End.

但如果我将主体更改为:

let _ =
  print_endline "The Start";
  my_getcwd () |> function
  | Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
  | Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
  ;
  print_endline "The End."
;;

...然后显然最后一个印刷声明("结束")丢失或者其他东西......

$ ./test2.native 
The Start
getcwd:
        /home/ttsiod/work/byePythonHelloOCaml

最初,我认为这是stdout缓冲未被刷新的情况。

print_endline的文档清楚地声称它冲刷了stdout,所以我不知所措 - 并且添加" flush"没有帮助,或者:

let _ =
  print_endline "The Start";
  my_getcwd () |> function
  | Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
  | Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
  ;
  print_endline "The End." ;
  flush stdout
;;

帮助?

1 个答案:

答案 0 :(得分:3)

print_endline被视为Error案例的一部分。从缩进来看,这显然不是你的意思,但不幸的是,OCaml编译器并没有对此发出警告。

您可以使用beginend(或只是括号)来使其有效:

let () =
  print_endline "The Start";
  my_getcwd () |> begin function
  | Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
  | Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
  end;
  print_endline "The End." ;
  flush stdout

或者,不使用;

let () =
  let () = print_endline "The Start" in
  let () = match my_getcwd () with
    | Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
    | Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
  in
  let () = print_endline "The End." in
  flush stdout