OCaml Печатать заявления - PullRequest
       15

OCaml Печатать заявления

13 голосов
/ 12 сентября 2011

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

Ответы [ 3 ]

21 голосов
/ 12 сентября 2011

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

ОБНОВЛЕНИЕ

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

# 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ожидается.

12 голосов
/ 12 сентября 2011

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

4 голосов
/ 18 октября 2015

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

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