簡體   English   中英

魔術sprintf功能 - 如何包裝?

[英]Magic sprintf function - how to wrap it?

我試圖打包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"

但它不適用於多個arg:

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

如何創建一個可以與任意數量的args一起使用的單個函數?

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"

但問題是我的函數的主要目的是做一些除了formatring以外的工作,所以我嘗試使用建議的代碼如下

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

使用格式化字符串調用continuation,因此您可以在返回之前使用生成的字符串執行任何操作。

編輯:要回答你的擴展問題,訣竅是將所有額外的工作放入延續:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM