OCaml Операции печати

Можно ли поставить инструкции печати для отладки/тестирования в блоках кода? Например, в Java вы можете использовать System.out.println("") в середине методов для проверки переменных или других вещей, но в OCaml будет ли работать команда типа print_string? Не вернет ли значение единицы типа, что приведет к ошибке, вместо того, чтобы разрешить вам ее распечатать?

Ответ 1

Все будет хорошо, если вы встраиваете печать в последовательность выражений.

UPDATE

Вот конкретный пример, потому что ответ выше был довольно коротким и, ну, ответы только со ссылками не являются хорошими ответами. Это классическая хвостовая рекурсивная формулировка факториала (да, скучная, но знакомая):

# 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, как и ожидалось.

Ответ 2

Так как OCaml не является чистым функциональным языком, существует много способов сделать это. Вот как я пишу этот код, только для конкретного примера.

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 (как и я), очень полезно узнать об этом.

Ответ 3

Вот простой пример, который показывает, что последовательности выражений, упомянутые в Ray Toal answer, не обязательно требуют скобок вокруг них:

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");