コードのブロックにデバッグ/テスト用の印刷ステートメントを置くことは可能ですか?たとえば、Javaでは、メソッドの途中でSystem.out.println("")
を使用して変数などをチェックできますが、OCamlではprint_string
仕事?それはあなたがそれを印刷することを許可する代わりに、ユニットタイプの値を返し、それゆえエラーを引き起こしませんか?
印刷物を 式シーケンス に埋め込むと問題ありません。
[〜#〜]更新[〜#〜]
上記の答えがかなり短かったので、具体的な例を示します。リンクだけの答えは良い答えではありません。これは、階乗の古典的な末尾再帰的定式化です(うん、退屈ですが、おなじみです)。
# let fac n =
let rec f i n acc =
if i >= n
then acc
else (Printf.printf "%8d%8d%8d\n" i n acc; f (i+1) n ((i+1)*acc))
in
f 0 n 1;;
val fac : int -> int = <fun>
# fac 5;;
0 5 1
1 5 1
2 5 2
3 5 6
4 5 24
- : int = 120
ここでは、印刷の副作用を確認できますが、結果は予想どおり120であることが判明しました。
OCamlはpure関数型言語ではないため、これを行うには多くの方法があります。具体的な例として、私がこの種のコードを書く方法を以下に示します。
let rec mylength list =
(* DEBUG *)
let () = Printf.printf "mylength here, null list: %b\n%!" (list = [])
in
(* DEBUG *)
match list with
| [] -> 0
| _ :: rest -> 1 + mylength rest
動作したら、(* DEBUG *)コメント内の内容を削除できます。
%!の使用に注意してください。バッファをフラッシュします。 (私と同じように)printf
を使用して多くのデバッグを行う場合、これについて学ぶことは本当に役に立ちます。
Ray Toalの回答 で説明されている式シーケンスは必ずしも括弧で囲む必要がないことを示す簡単な例を次に示します。
let get_a_string =
let a_string = "a string" in
(* The semicolon causes the return value of the statement to be discarded *)
Printf.printf "Debug: %s\n" a_string;
a_string
let () = Printf.printf "Result: %s\n" get_a_string
関数の戻り値を破棄する別の方法は、ignore
を使用することです。
ignore (Printf.printf "Debug info");