7

是否可以部分应用一个功能,例如bprintf并防止它根据其初始用途受到限制?

我想做以下事情:

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

3 回答 3

12

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

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

错误 FS0030:值限制。值 'append' 已被推断为具有通用类型 val append : ('_a -> '_b) when '_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"

这将工作得很好。

于 2010-10-28T21:35:03.923 回答
9

您可以添加显式格式参数

let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"
于 2010-10-28T21:30:02.917 回答
6

您遇到了 F# 值限制。

下面是一些解决方法的一个很好的解释:Understanding F# Value Restriction Errors

这是一篇相当深入的文章,解释了其背后的原因:链接

于 2010-10-28T21:35:30.423 回答