Types 使用值的漂亮打印机从值中获取字符串

Types 使用值的漂亮打印机从值中获取字符串,types,ocaml,Types,Ocaml,我已经编写了很多漂亮的打印机,类型是out\u channel->'a->unit,现在我想要一段代码,通过使用漂亮的打印机从值中获取字符串 例如,我已经实现了以下功能: type t = { x: int; y: int } let co = { x = 4; y = 5 } let print (chan: out_channel) (co: t) : unit = Printf.fprintf chan "(%d, %d)" co.x co.y 我认为函数Printf

我已经编写了很多漂亮的打印机,类型是
out\u channel->'a->unit
,现在我想要一段代码,通过使用漂亮的打印机从值中获取字符串

例如,我已经实现了以下功能:

type t =
  { x: int;
    y: int }

let co = { x = 4; y = 5 }

let print (chan: out_channel) (co: t) : unit =
  Printf.fprintf chan "(%d, %d)" co.x co.y
我认为函数
Printf.sprintf
可以帮助我获取字符串
(4,5)
。我尝试了
Printf.sprintf“%a”print co
,它在
print
的位置给了我一个错误:
这个表达式有type out\u channel->t->unit,但是应该是type unit->'a->string
的表达式


是否有人知道如何提醒这一行,或者是否有人除了
sprintf
之外的解决方案?

恐怕我不清楚您需要什么,所以让我猜猜:

let prints (co: t) : string =
  Printf.sprintf "(%d, %d)" co.x co.y

let print ch co = Printf.fprintf ch "%s" (prints co)

# print stdout co;;
(4, 5)- : unit = ()

出于类型检查的原因,无法在sprintf的格式化指令中直接使用
%a
。 如果您能负担得起使用
格式
而不是
Printf
,事情就会简单得多:

  • 如果您使用OCAML4.01,那么您直接拥有一个
    格式的.asprintf
    ,根据文档,它可以满足您的需要
  • 如果您有一个较早的版本,那么通过使用一个临时缓冲区来创建格式化程序,很容易模拟这种行为。然后,您可以向该格式化程序写入数据,完成后,只需检索缓冲区的内容即可
事实上,您必须使用
Format.kfprintf
,以便可以使用任意格式函数:

  let sfprintf fmt =
    let b = Buffer.create 20 in
    let return fmt = Format.pp_print_flush fmt (); Buffer.contents b in
    Format.kfprintf return (Format.formatter_of_buffer b) fmt

  let s = sfprintf "%a" print co
同样的技术也可以应用于
Printf
格式化函数,但这里还有另一个问题:无法从
缓冲区.t
中创建
输出通道。我能想到的最接近的方法是依赖
Unix
模块的
pipe
功能:

let sfprintf fmt =
  let (infd,outfd) = Unix.pipe () in
  let inc = Unix.in_channel_of_descr infd in
  Unix.set_nonblock infd;
  let outc = Unix.out_channel_of_descr outfd in
  let return outc =
    Printf.fprintf outc "%!";
    let b = Buffer.create 10 in
    try
      while true do 
        Buffer.add_char b (input_char inc) done;
      assert false;     
    with Sys_blocked_io -> 
      Unix.close outfd; Unix.close infd; Buffer.contents b
  in
  Printf.kfprintf return outc fmt;;

let s = sfprintf "%a" print co

我认为这是不可能的。如果有人愿意做你想做的事,我真的很想看到结果。