这是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 []):字节[],
System.Text.Encoding.GetBytes(s:string):字节[] Blockquote
有什么办法可以组成更正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
类型的组合函数选择正确的重载?
答案 0 :(得分:5)
您始终可以添加注释:
let composedFunction : string -> _ = System.Text.Encoding.UTF8.GetBytes >> Array.length
或
let composedFunction = (System.Text.Encoding.UTF8.GetBytes : string -> _) >> Array.length
答案 1 :(得分:1)
如您的示例所示,.NET方法并不总是能很好地构成-我认为在这种情况下,惯用的方法只是在处理.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
这很有趣,但是正如我所说,我永远不会真正使用它,因为上面定义的普通函数更容易理解。