保持部分应用的功能通用

Dan*_*iel 7 generics f# value-restriction

是否可以部分应用诸如bprintf并根据其初始使用限制其功能?

我想做以下事情:

let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 12

引起这种情况的F#方面称为值限制.您可以看到,如果只输入两个let声明到F#Interactive(这样编译器就不会从第一次使用中推断出类型):

> let builder = new System.Text.StringBuilder() 
  let append = Printf.bprintf builder ;;
Run Code Online (Sandbox Code Playgroud)

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

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

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

这将工作得很好.


des*_*sco 8

你可以添加显式格式参数

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

  • 因为在.NET中,函数可以是通用的,而变量则不是.`let append format =`描述一个函数; `let append =`描述一个变量. (11认同)

Tim*_*son 6

您遇到了F#值限制.

以下是一些解决方法的一个很好的解释:了解F#值限制错误

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