结束Format.formattter

时间:2017-07-13 17:37:38

标签: ocaml

我正在尝试定义一个函数msg,它允许使用Format库打印调试消息,并带有一个选项来控制它们是否通过debug标志显示(从命令设置)线)。这是我天真的第一次尝试:

let debug = ref false

let msg =
  let open Format in
  (if !debug then fprintf err_formatter else ifprintf err_formatter)

不幸的是,这不起作用,给我以下错误消息:

Error: The type of this expression,
       ('_a, Format.formatter, unit) format -> '_a,
       contains type variables that cannot be generalized

我做错了什么?谢谢!

1 个答案:

答案 0 :(得分:1)

这是价值限制。你可以通过“eta扩展”解决它:

let msg x =
    let open Format in
    if !debug then fprintf err_formatter x
    else ifprintf err_formatter x

简单地说,价值限制通过禁止除简单值以外的任何其他东西的泛化(处理为完全多态)来避免不健全的行为。您对msg的定义不是一个简单的值。在eta扩展之后,定义是一个简单的值(lambda)。您可以在此处阅读更多内容:Jacques Garrigue, Relaxing the Value Restriction

新代码对我有用:

# let debug = ref true
val debug : bool ref = {contents = true}

# let msg x =
    let open Format in
    if !debug then fprintf err_formatter x
    else ifprintf err_formatter x;;
val msg : ('a, Format.formatter, unit) format -> 'a = <fun>

# let open Format in
  msg "%d " 1; msg "%s" "red rose that I mean";
  pp_print_flush err_formatter ();;
1 red rose that I mean- : unit = ()
#