web-dev-qa-db-ja.com

F#:String.Joinおよび|>演算子

F#インタラクティブでは、String.Join("+", ["a"; "b"])を正常に使用できますが、

["a"; "b"] |> String.Join "+"

エラーが発生します:

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

パイプラインを使用してコレクションを渡すString.Joinを使用するにはどうすればよいですか?

P.S.同じ問題がlines |> File.WriteAllLines "filename.txt"にもあります

39

_String.Join_は.NETメソッドです。 .NETメソッドを使用する場合、F#はそれをタプルを引数として受け取る関数と見なします(呼び出す場合は、パラメーターをf(a, b)として記述します)。 _|>_演算子は、パラメーターのカレー形式を使用する関数で使用できます(_f a b_と書くことで呼び出すことができます) 。

代わりに、F#ライブラリ(同じことを行う)の関数_String.concat_を使用できます。

_["a"; "b"] |> String.concat "+"
_

[〜#〜] edit [〜#〜] _File.WriteAllLines_も同じです。パイプラインの一部として使用する場合は、呼び出しをラップするF#関数を記述できます。

_let writeAllLines file (lines:seq<string>) =
  System.IO.File.WriteAllLines(file, lines)
_

一般に、演算子の左側にすべての引数を記述したい場合にのみ、.NETメソッドで_|>_を使用できます。たとえば、次のように書くことができます。

_("+", ["a"; "b"]) |> System.String.Join
_

...しかし、それはパイプライン演算子の通常の使用には適合しません。 .NET APIを使用する場合、パイプラインは機能ライブラリでのみ適切に機能するため、通常はC#のようなスタイルのプログラミング(パイプラインなし)を使用することをお勧めします。

67
Tomas Petricek

私は別の方法を検討すると思いました。 OPはString.Joinについて具体的に質問しましたが、Tomas Petricekの答えはそのメソッドに対して完全に正しいです(F#ライブラリのString.concatを使用してください)。

重複した引数を取る別のメソッドについて話しているが、それらをカレーとして使用したい場合は、次のヘルパー関数を使用できます。

let partial f x y = f(x, y)

これにより、メソッドを「partial」に渡して、カリー化された関数を取り戻すことができます。次のように使用します。

let partial f x y = f(x, y)
myCollection |> partial String.Join "&"
19
Richiban