Определение функции, возвращающей другую функцию на основе ссылки - PullRequest
0 голосов
/ 25 мая 2020

Следующий фрагмент кода не работает так, как я думал:

let debug_flag = ref false

let dprintf = let open Printf in
  match !debug_flag with
  | true -> printf
  | false -> ifprintf stdout

let test_dprintf () =
  begin
    debug_flag := true;
    Printf.printf "print1\n";
    dprintf "print2\n";
    Printf.printf "print3\n";
    debug_flag := false
  end

Я ожидал, что он выведет

print1
print2
print3

Однако он печатает только

print1
print3

Назначение true на debug_flag в test_dprintf, похоже, вообще не влияет.

Кто-нибудь знает почему? И если да, то знаете ли вы о возможном способе обхода?

Я использую OCaml 4.09.0

Спасибо за ваши ответы

1 Ответ

2 голосов
/ 25 мая 2020

Определение dprintf не является функциональным выражением. Это выражение, которое вернет функцию, но само выражение будет оцениваться только при оценке определения dprintf, а не при вызове возвращаемой им функции.

Чтобы решить эту проблему, вы можете просто сделать аргумент явный:

let dprintf fmt = let open Printf in
  match !debug_flag with
  | true -> printf fmt
  | false -> ifprintf stdout fmt

Теперь тело dprintf будет оцениваться при его вызове.

...