Я хотел бы сделать функцию в F #, которая принимает функцию типа printf как аргумент, и использует этот аргумент для вывода данных. Использование было бы что-то вроде следующего:Как передать функцию стиля printf другой функции в F #
OutputStuff printfn
Моя первая попытка была, чтобы фигура компилятор все из него для меня:
let OutputStuff output =
output "Header"
output "Data: %d" 42
Это терпит неудачу, потому что он решает, что output
функция принимает string
и возвращая unit
, поэтому второй вызов завершается с ошибкой.
Далее я попытался объявить output
иметь ту же сигнатуру, как printfn
:
let OutputStuff (output : Printf.TextWriterFormat<'a> -> 'a) =
output "Header"
output "Data: %d" 42
Это терпит неудачу, потому что компилятор решает, что реальный тип output
является Printf.TextWriterFormat<string> -> unit
, поэтому снова второй вызов терпит неудачу. Он также генерирует предупреждение FS0064, указывающее, что первый вызов output
заставляет код быть менее общим, чем аннотации типа, что является основной проблемой здесь.
Наконец, я попытался объявить функцию вывода в виде отдельного типа аббревиатуры:
type OutputMe<'a> = Printf.TextWriterFormat<'a> -> 'a
let OutputStuff (output : OutputMe<'a>) =
output "Header"
output "Data: %d" 42
Это терпит неудачу с теми же результатами, что и предыдущая попытка.
Как убедить компилятор не специализировать тип output
и оставить его как Printf.TextWriterFormat<'a> -> 'a
?
Do вам действительно нужно передать функцию, подобную printf? Если у вас есть какая-то функция, которую вы хотите использовать, которая берет 'string', и вы хотите называть ее форматированной строкой, просто используйте' Printf.ksprintf' с вашей функцией. –
Близко связанные: http://stackoverflow.com/questions/5569909/how-do-i-create-an-f-function-with-a-printf-style-logging-argument – Charlie
Вы также можете найти это полезным - в нижней части этого файла ([Pervasive.fs] (https://github.com/jack-pappas/ExtCore/blob/master/ExtCore/Pervasive.fs)) есть некоторые написанные мной функции, которые берут произвольную строку формата и которые используют «Printf.ksprintf» под капотом. –