我正在尝试定义一个函数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
我做错了什么?谢谢!
答案 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 = ()
#