F#:String.Join和|>运算符

boh*_*nko 37 f# f#-interactive

在F#interactive中,我可以String.Join("+", ["a"; "b"])成功使用,但是

["a"; "b"] |> String.Join "+"
Run Code Online (Sandbox Code Playgroud)

产生错误:

Script1.fsx(79,15): error FS0001: This expression was expected to have type
    string list -> 'a    
but here has type
    string
Run Code Online (Sandbox Code Playgroud)

如何String.Join使用管道传递集合?

PS同样的问题是 lines |> File.WriteAllLines "filename.txt"

Tom*_*cek 62

String.Join是一种.NET方法.使用.NET方法时,F#将其视为一个以元组作为参数的函数(在调用它时将参数写为f(a, b)).的|>操作员可以与使用功能一起使用咖喱形式的参数(并且可以通过书面形式称为f a b).

您可以使用String.concatF#库中的函数(它执行相同的操作):

["a"; "b"] |> String.concat "+"
Run Code Online (Sandbox Code Playgroud)

编辑 File.WriteAllLines也是一样的情况.如果要将它用作管道的一部分,可以编写一个包装调用的F#函数:

let writeAllLines file (lines:seq<string>) =
  System.IO.File.WriteAllLines(file, lines)
Run Code Online (Sandbox Code Playgroud)

通常,|>只有在要在运算符左侧写入所有参数时,才能使用.NET方法.你可以写例如:

("+", ["a"; "b"]) |> System.String.Join
Run Code Online (Sandbox Code Playgroud)

......但这与通常使用的管道运营商不符.使用.NET API时,通常最好使用类似C#的编程风格(没有流水线操作),因为管道仅适用于功能库.


Ric*_*ban 15

我以为我会用另一种方法来衡量.OP专门询问了String.Join,而Tomas Petricek的回答对于该方法是完全正确的(使用来自F#库的String.concat).

如果您正在讨论另一种采用tupled参数的方法,但是您希望将它们用作curried,则可以使用此辅助函数:

let partial f x y = f(x, y)
Run Code Online (Sandbox Code Playgroud)

这允许您将方法传递给'partial'并返回curried函数.像这样使用它:

let partial f x y = f(x, y)
myCollection |> partial String.Join "&"
Run Code Online (Sandbox Code Playgroud)