Ocaml 带有可选参数的Printf错误

Ocaml 带有可选参数的Printf错误,ocaml,Ocaml,假设我编写这个函数: let f ?(x=0) fmt y = Format.fprintf fmt "%d" (x+y) 它的类型是:?x:int->Format.formatter->int->unit 我可以称之为指定x,也可以不指定 现在,让我们这样称呼它: let () = Format.printf "%a@." f 0 let f ?(x=0) () fmt y = Format.fprintf fmt "%d" (x+y) 我有一个错误: Error: This expre

假设我编写这个函数:

let f ?(x=0) fmt y = Format.fprintf fmt "%d" (x+y)
它的类型是:
?x:int->Format.formatter->int->unit

我可以称之为指定
x
,也可以不指定

现在,让我们这样称呼它:

let () = Format.printf "%a@." f 0
let f ?(x=0) () fmt y = Format.fprintf fmt "%d" (x+y)
我有一个错误:

Error: This expression has type ?x:int -> Format.formatter -> int -> unit
       but an expression was expected of type Format.formatter -> 'a -> unit
我不明白为什么这会是个问题。这个参数是可选的,如果我不把它放进去,它应该是可以的,不是吗?(显然,编写
Format.printf“%a”(f~x:0)0
是可行的,但使用可选参数有什么意义?)

我的意思是,如果我这样声明我的函数:

let () = Format.printf "%a@." f 0
let f ?(x=0) () fmt y = Format.fprintf fmt "%d" (x+y)

它的类型将是:
?x:int->()->Format.formatter->int->unit
并调用
Format.printf'%a@.“(f())0将起作用。因此,我猜可选参数不能作为函数的最后一个参数存在问题,但它不是。

这个问题源于非常灵活的
printf类型:
('a,Format.formatter,unit)Format->'a
。这时,typechecker推断出
f
的预期类型是
Format.formatter->int->unit
,应用可选参数为时已晚。在这种情况下,即使稍微帮助一下打字员也可以解决问题(但会破坏公国)


请注意,这是一个非常普遍的问题,高阶函数在处理带有标记或可选参数的函数参数时会遇到一些困难

我不明白的是,为什么添加
()
参数可以使它工作。通过
()
参数,typechecker可以推断在检查
f()
时省略了可选参数,因此推断更加局部;而在
printf
应用程序中,可选参数的消除依赖于来自应用程序上下文的类型信息。