Im using a resource file for strings, and then use also those with placeholders and needs to format the strings.
I have (about) the following code in my project:
let create s = sprintf (Printf.StringFormat<_>(s))
let formatstring = "%s:%d" // this is actually then gotten from the resource strings
let createsomespecificstring s d = create formatstring s d
let resultstring = createsomespecificstring "123" 123
This code works when I use f#3.0. Swapping it to compile it with 3.1, it compiles but gives a runtime error:
Unable to cast object of type 'Final2@235[Microsoft.FSharp.Core.Unit,System.String,System.String,System.String,System.String]' to type 'Microsoft.FSharp.Core.FSharpFunc
2[Microsoft.FSharp.Core.FSharpFunc
2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.PrintfImpl+PrintfEnv3[Microsoft.FSharp.Core.Unit,System.String,System.String]],Microsoft.FSharp.Core.FSharpFunc
2[System.String,Microsoft.FSharp.Core.FSharpFunc`2[System.String,System.Object]]]'.
If Im running the above code in repl it doesnt work at all with:
stdin(28,5): error FS0030: Value restriction. The value 'resultstring' has been inferred to have generic type val resultstring : '_a
Either define 'resultstring' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
The above code somewhat defeats the purpose of strong typing again, but its kind of nice when one has resource strings.
Am I doing something wrong (besides mentioned above)?
Any ideas on how to do it better and even make it work (especially in 3.1)?
Edit: After first answer (which works in that specific case) the number of formating options/arguments are "random" length:
let formatstring = "%s:%d:%d"
let createsomespecificstring s d d' = create formatstring s d d'
let resultstring = createsomespecificstring "123" 123 345
Then it does not work again.