F# 神奇的sprintf函数-如何包装它?

F# 神奇的sprintf函数-如何包装它?,f#,F#,我正在尝试包装对sprintf函数的调用。以下是我的尝试: let p format args = "That was: " + (sprintf format args) let a = "a" let b = "b" let z1 = p "A %s has invalid b" a 这似乎是可行的,但输出是有效的 val p : format:Printf.StringFormat<('a -> string)> -> args:'a -> strin

我正在尝试包装对
sprintf
函数的调用。以下是我的尝试:

let p format args = "That was: " + (sprintf format args)

let a = "a"
let b = "b"

let z1 = p "A %s has invalid b" a 
这似乎是可行的,但输出是有效的

val p : format:Printf.StringFormat<('a -> string)> -> args:'a -> string
val a : string = "a"
val b : string = "b"
val z1 : string = "That was: A a has invalid b"
我得到编译时错误:

let z2 = p "A %s has invalid b %A" a b;;
---------^^^^^^^^^^^^^^^^^^^^^^^^^^^

stdin(7,10): error FS0003: This value is not a function and cannot be applied
如何创建一个可以处理任意数量参数的函数

UPD。托马斯建议使用

let p format = Printf.kprintf (fun s -> "This was: " + s) format
它确实有效。这里有一个例子

let p format = Printf.kprintf (fun s -> "This was: " + s) format

let a = p "something like %d" 123
// val p : format:Printf.StringFormat<'a,string> -> 'a
// val a : string = "This was: something like 123"
而且它不再起作用了:

  let z = q "something like %d" 123;;
  ----------^^^^^^^^^^^^^^^^^^^

stdin(30,15): error FS0001: The type ''c -> string' is not compatible with the type 'Printf.TextWriterFormat<('a -> 'b)>'
让z=q“类似于%d”123;;
----------^^^^^^^^^^^^^^^^^^^
stdin(30,15):错误FS0001:类型“c->string”与类型“Printf.textWritePerformat”不兼容

我怎样才能修好它

为此,您需要使用curry-您的函数
p
需要采用
格式
并返回一个由
printf
函数之一返回的函数(该函数可以是一个包含一个或多个参数的函数)

这不能使用
sprintf
来完成(因为这样您就必须显式地传播参数。但是,您可以使用
kprintf
,它将延续作为第一个参数::

let p format = Printf.kprintf (fun s -> "This was: " + s) format
使用格式化字符串调用continuation,因此您可以在返回之前对结果字符串执行任何需要的操作

编辑:要回答您的扩展问题,诀窍是将所有额外的工作放在继续部分:

let q format = 
  let cont z =
    // Some work with formatted string
    printf "%s" z 
  Printf.kprintf cont format 

+1谢谢你的建议。我的情况有点复杂。你能看看这个问题的最新进展吗?主要问题是我不知道像“xxx%s”这样的字符串是如何转换成
StringFormatter
类的,以及在我编写
printfn“%时会发生什么事情。”12
。也许你有任何解释的链接?@Rustam-你必须把你想对格式化字符串所做的所有工作都放在继续部分。参见扩展示例。对不起,这是你的
q
函数中的一个输入错误吗?我不知道你是如何使用你定义的
cont
非常感谢你!
let p format = Printf.kprintf (fun s -> "This was: " + s) format
let q format = 
  let cont z =
    // Some work with formatted string
    printf "%s" z 
  Printf.kprintf cont format