保持部分应用的功能通用

时间:2010-10-28 21:27:18

标签: generics f# value-restriction

是否可以部分应用bprintf这样的功能,并防止它因初次使用而受到限制?

我想做以下事情:

let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value

3 个答案:

答案 0 :(得分:12)

导致此问题的F#方面称为值限制。您可以看到,如果只向F#Interactive输入两个let声明(以便编译器不会从第一次使用中推断出类型):

> let builder = new System.Text.StringBuilder() 
  let append = Printf.bprintf builder ;;
  

错误FS0030:值限制。推断值'append'具有       泛型类型val附加:('_ a - >'_ b)'_a:> Printf.BuilderFormat<'_ B个       要么使参数'append'显式,要么如果你不打算       它是通用的,添加一个类型注释。

来自F#团队的excellent article by Dmitry Lomov详细解释了它。正如文章所建议的,一种解决方案是添加显式类型参数声明:

let builder = new System.Text.StringBuilder() 
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder 
append "%i" 10 
append "%s" "Hello"

这样可以正常使用。

答案 1 :(得分:8)

您可以添加显式的格式参数

let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"

答案 2 :(得分:6)

您遇到了F#值限制。

以下是一些解决方法的详细解释:Understanding F# Value Restriction Errors

这是一篇相当深入的文章,解释其背后的原因:http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx