gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 00:26:10 25 4
gpt4 key购买 nike

我正在尝试结束对 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

我得到编译时错误:
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

如何创建一个可以与任意数量的参数一起使用的函数?

更新 . Tomas 建议使用
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 q format = 
let z = p format // p is defined as suggested
printf z // Some work with formatted string

let z = q "something like %d" 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)>'

我该如何解决?

最佳答案

为此,您需要使用柯里化(Currying) - 您的函数 p需要拍format并返回由 printf 之一返回的函数函数(它可以是一个带有一个或多个参数的函数)。

使用 sprintf 无法做到这一点(因为那样你就必须显式地传播参数。但是,你可以使用 kprintf 它将延续作为第一个参数::

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

关于f# - 神奇的 sprintf 函数 - 如何包装它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22760998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com