【问题标题】:How to pick correct method overload for function composition?如何为函数组合选择正确的方法重载?
【发布时间】:2019-02-20 20:57:26
【问题描述】:

这是F#中函数的简单组合

let composedFunction = System.Text.Encoding.UTF8.GetBytes >> Array.length
"test" |> composedFunction

类型推断正确定义了组合函数string -> int 的类型。但是编译器无法选择System.Text.Encoding.UTF8.GetBytes 方法的正确重载:

错误 FS0041:方法“GetBytes”的唯一重载不能 根据此程序点之前的类型信息确定。一种 可能需要类型注释。候选人:

System.Text.Encoding.GetBytes(chars: char []) : byte [],

System.Text.Encoding.GetBytes(s: string) : byte []Blockquote

有没有办法compose纠正接受字符串参数的System.Text.Encoding.UTF8.GetBytes的重载?

当然,我可以做以下

// declare function which calls correct overload and then use it for compostion
let getBytes (s: string) = System.Text.Encoding.UTF8.GetBytes s      
let composedFunction = getBytes >> Array.length

// start composition with ugly lambda
let composedFunction =
  (fun (s: string) -> s) >> System.Text.Encoding.UTF8.GetBytes >> Array.length

但我想知道是否有任何方法无需额外的函数声明来使编译器根据推断的string -> int类型的组合函数来选择正确的重载?

【问题讨论】:

  • 您是否尝试在函数上指定类型,例如let composedFunction : string -> _ = ...

标签: f#


【解决方案1】:

您可以随时添加注释:

let composedFunction : string -> _ = System.Text.Encoding.UTF8.GetBytes >> Array.length

let composedFunction = (System.Text.Encoding.UTF8.GetBytes : string -> _) >> Array.length

【讨论】:

    【解决方案2】:

    正如您的示例所示,.NET 方法并不总是能够很好地组合 - 我认为在这种情况下的惯用方法是在处理 .NET 库时使用 .NET 样式(并在您处理时使用函数式样式)重新处理函数库)。

    在您的具体情况下,我将只定义一个带有类型注释的普通函数,并使用 Length 成员而不是使用函数来获取长度:

    let composedFunction (s:string) = 
      System.Text.Encoding.UTF8.GetBytes(s).Length
    

    现有答案显示了如何使组合与类型注释一起使用。您可以做的另一个技巧(我绝对不会在实践中使用)是您可以将 string 上的标识函数添加到组合中以限制类型:

    let composedFunction = id<string> >> System.Text.Encoding.UTF8.GetBytes >> Array.length
    

    这很有趣,但正如我所说,我永远不会真正使用它,因为上面定义的普通函数更容易理解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-19
      • 1970-01-01
      • 2020-02-13
      • 2019-03-26
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多