【问题标题】:Keeping partially applied function generic保持部分应用函数通用
【发布时间】:2011-05-02 03:07:59
【问题描述】:

是否可以部分应用bprintf之类的函数,并防止其基于初始使用受到限制?

我想做以下事情:

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

【问题讨论】:

    标签: generics f# value-restriction


    【解决方案1】:

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

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

    错误 FS0030:值限制。值“附加”已被推断为 通用类型 val append : ('_a -> '_b) when '_a :> Printf.BuilderFormat 要么明确“附加”的参数,或者,如果你不打算 它是通用的,添加一个类型注释。

    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"
    

    这样就可以了。

    【讨论】:

      【解决方案2】:

      你可以添加明确的格式参数

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

      【讨论】:

      • 谢谢。谁能解释为什么这有效而部分应用程序无效?
      • 因为在 .NET 中,函数可以是泛型的,而变量不能。 let append format = 描述了一个函数; let append = 描述了一个变量。
      【解决方案3】:

      您遇到了 F# 值限制。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        相关资源
        最近更新 更多