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 + PrintfEnv 3[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.

+3


source to share


2 answers


Type annotation as @kvp at hints is the "correct" answer.

let createsomespecificstring s d d' : string = create formatstring s d d'

      



This does it in fsi and in f # 3.1 when compiled with the tests I ran.

+1


source


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.

0


source







All Articles