带有可选参数的 printf 错误

  • 本文关键字:printf 错误 参数 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

我有这个错误:

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 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 。当类型检查器推断出预期的f类型Format.formatter -> int -> unit时,应用可选参数为时已晚。在这种情况下,即使帮助打字器一点也可以解决问题(但打破了公国性(

let pf fmt f = Format.printf fmt f
let () = pf "%a@." f 0 (* works *)

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

最新更新