Строки нелитерального формата F # printf - как сделать их доступными в качестве параметров?

Я хотел бы использовать нелитеральные строки для параметра «формат» функции типа ведения журнала, как показано здесь:

// You need to make c:\testDir or something similar to run this.....
//
let csvFile = @"c:\testDir\foo.csv"

open System.IO

let writer file (s:string) =
  use streamWriter = new StreamWriter(file, true)
  streamWriter.WriteLine(s)
  // s

let log format = Printf.ksprintf (writer csvFile) format

let oneString format = (Printf.StringFormat<string->string> format)

let format = oneString "(this does not %s)"

//log format "important string"

log "this works %s" "important string"

В моей первой попытке использовалась литеральная строка, и приведенный выше фрагмент должен работать нормально для вас, если вы создадите нужный каталог или аналогичный.

Обнаружив, что вы не можете просто «разрешить привязку» строки формата, я узнал о Printf.StringFormatи более подробной информации о Printf.ksprintf, но я явно что-то упускаю, потому что не могу заставить их работать вместе с моим небольшим примером.

Если вы закомментируете последнюю строку и восстановите предыдущую, вы увидите ошибку компилятора.

Почти помогло заставить функцию writer возвращать строку (раскомментировать ее последнюю строку), но тогда log возвращает строку (это означает, что каждый вызов теперь нуждается в ignore).

Я хотел бы знать, как динамически устанавливать мои строки формата в мире проверенных типов F # printf!

Обновление Я добавил параметр format в log, чтобы избежать ошибки ограничения значения, которая возникает, если log не вызывается позже, как в моем примере. Я также меняю fmt на format в oneString.

Обновить

Это вопрос, отличный от этот. Этот вопрос не показывает, что аргумент функции передается в Printf.StringFormat (незначительная разница), и в нем нет части о том, что Printf.ksprintf не принимает функцию продолжения, которая возвращает единицу.

Я думал, что нашел решение с:

let oneString format = (Printf.StringFormat<string->string,unit> format)

это компилируется, но есть ошибка времени выполнения. (Изменение ,unit)


person GMc    schedule 28.08.2015    source источник
comment
Это то, что вы ищете: заголовок stackoverflow.com/questions/19202773/   -  person John Palmer    schedule 29.08.2015
comment
ваш ответ на этот вопрос помог мне найти Printf.StringFormat, но он не объясняет, почему мне нужно раскомментировать //s в writer, чтобы все работало (я хочу, чтобы writer возвращал unit). Я подозреваю, что мне не хватает какой-то тонкости проверки типов.   -  person GMc    schedule 29.08.2015
comment
Я немного возился с этим вчера. Я думаю, вам будет полезно добавлять явные аннотации типов ко всему. В какой-то момент мне удалось заставить код скомпилироваться и сделать то, что вы просили, но при втором запуске я попал в состояние, которое выдает ошибку времени выполнения.   -  person Robert Sim    schedule 31.08.2015