The aspect of F# that's causing this is called value restriction. You can see that if you enter just the two let
declarations to F# Interactive (so that the compiler doesn't infer the type from the first use):
> let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder ;;
error FS0030: Value restriction. The value 'append' has been inferred to have
generic type val append : ('_a -> '_b) when '_a :> Printf.BuilderFormat<'_b>
Either make the arguments to 'append' explicit or, if you do not intend for
it to be generic, add a type annotation.
There is an excellent article by Dmitry Lomov from the F# team which explains it in detail. As the article suggests, one solution is to add explicit type parameter declaration:
let builder = new System.Text.StringBuilder()
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder
append "%i" 10
append "%s" "Hello"
This will work just fine.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…