Continuous registration in F #
I am trying to create 2 registration functions, one for printing directly to stdout, the other for printing with an antecedent string [Error]
.
let log message =
printfn message
let twError (tw:System.IO.TextWriter) message =
tw.Write("[Error] {0}", message)
let error (message:Printf.StringFormat<_>) =
let format = Printf.TextWriterFormat<_>(sprintf "[Error] %A" message)
log format
let date = System.DateTime.Now
log "%A" twError date
error "%s" <| date.ToString()
As you can see, in the function error
I need to create a new string and then convert it to type TextWriterFormat
. But this will be less efficient than a direct call to the stream, how to change the function error
to make it more efficient?
source to share
You want a Printf.kprintf
family of functions. Their documentation is very difficult to understand, but the concept is simple:
-
printf
takes a format string (and arguments), formats it, then prints it to the console -
sprintf
takes a format string (and arguments), formats it, and then returns it as a string -
kprintf
takes a format string (and arguments), formats it, and then passes it (as a string) to a function you provide. This function should take a string and do whatever you want with it.
For example:
open Printf
let addDateTime (s : string) =
sprintf "%A: %s" DateTime.UtcNow s
sprintf "%A" [1; 2; 3] // Returns "[1; 2; 3]"
kprintf addDateTime "%A" [1; 2; 3] // Returns "2017-05-26 06:05:00: [1; 2; 3]"
let printDateTime (s : string) =
printfn "%A: %s" DateTime.UtcNow s
printfn "%A" [1; 2; 3] // Prints "[1; 2; 3]"
kprintf printDateTime "%A" [1; 2; 3] // Prints "2017-05-26 06:05:00: [1; 2; 3]"
So, your function error
might just become:
let errorLogger (s : string) = printfn "[Error] %s" s
let error msg = kprintf errorLogger msg
error "Oops: %A" [1; 2; 3] // Prints "[Error] Oops: [1; 2; 3]"
Experiment with a kprintf
little more and see what you can do with it. This is a very powerful feature and it is a shame that no more people know about it.
source to share