F #: составление sprintf со строкой -> единичная функция для форматирования - PullRequest
2 голосов
/ 09 августа 2011

Там есть информация о том, как сделать пользовательскую обработку для формата и его частей . Я хочу сделать что-то немного проще, в частности, я хочу сделать что-то с эффектом:

let writelog : string -> unit = ... // write the string to the log

let writelogf = sprintf >> writelog // write a formatted string to the log

Я не слишком удивлен, что компилятор смущен этим, но есть ли способ заставить его работать?

Ответы [ 2 ]

12 голосов
/ 09 августа 2011

Самый простой способ определить собственную функцию, которая принимает строку форматирования, например printf, - это использовать функцию Printf.kprintf.Первый аргумент kprintf - это функция, которая используется для отображения результирующей строки после форматирования (чтобы вы могли передать ее своей функции writelog):

let writelog (s:string) = printfn "LOG: %s" s
let writelogf fmt = Printf.kprintf writelog fmt

Переданный параметр fmtв качестве второго аргумента используется строка специального формата.Это работает лучше, чем решение jpalmer , потому что если вы укажете некоторые дополнительные аргументы, они будут напрямую переданы kprintf (поэтому число аргументов может зависеть от строки форматирования).

Вы можете написать:

> writelogf "Hello";;
LOG: Hello

> writelogf "Hello %d" 42;;
LOG: Hello 42
1 голос
/ 09 августа 2011

Это работает

> let writelog = fun (s:string) -> printfn "%s" s;;

val writelog : string -> unit

> let writelogf arg = sprintf arg >> writelog;;

val writelogf : Printf.StringFormat<('a -> string)> -> ('a -> unit)

> writelogf "hello %s" "world";;
hello world
val it : unit = ()
>

(сессия от FSI)

ключ в дополнительном аргументе для writelogf

...