F # error with sprintf and format
Im using a resource file for strings and then use also those that have placeholders and need to format the strings.
I have 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. Rearranging it to compile it with 3.1, it compiles but gives a runtime error:
Cannot use object of type 'Final2 @ 235 [Microsoft.FSharp.Core.Unit, System.String, System.String, System.String, System.String]' for input '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 executing the above code in repl, it doesn't work at all with:
stdin (28,5): error FS0030: value limitation. The value "resultstring" was inferred to be of the general type val resultstring: '_a
Either define "resultstring" as a simple data term, make it a function with explicit arguments, or if you are not going to use it, add a type annotation.
The above code somewhat defeats the purpose of strong typing, but it looks nice when it has resource strings.
Am I doing anything wrong (besides the one mentioned above)?
Any ideas on how to make this better and even make it work (especially in 3.1)?
Edit: After the first answer (which works in this particular case), the number of formatting options / arguments is a "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 doesn't work again.
source to share
Here's a solution that works at least in fsi:
let create s = sprintf (Printf.StringFormat<_ -> _ -> string >(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
All I needed was to add additional dummy parameters and force the return type of sprintf into a string.
source to share