パイプ演算子 |> (F#)

この演算子はイイ!

UNIX系のコマンドは、以下のようにパイプで連結して使われることがよくある。

% ls | grep hoge

これと同じようなことがF#の関数呼び出しで出来るのだ。

#light
let numbers = [ 1; 4; 2; 5; 2; 6; 9]
List.iter (fun x -> printfn "%i" x) numbers     // (A)
numbers |> List.iter (fun x -> printfn "%i" x)  // (B)

(A)と(B)は等価だ。(A)の最後の引数を、先頭に持ってきて |> 演算子で後ろの関数に渡すことが出来る。

では、応用にいってみよう。

#light
let methods =
  AppDomain.CurrentDomain.GetAssemblies() // アセンブリの配列を取得
  |> List.of_array  // 配列をリストに変換
  |> List.map (fun asm -> asm.GetTypes()) // 各アセンブリからタイプを取得
  |> Array.concat   // 一本の配列に連結
  |> List.of_array  // 配列をリストに変換
  |> List.map (fun t -> t.GetMethods())   // 各タイプからメソッドを取得
  |> Array.concat   // 一本の配列に連結

printfn "%A" methods

UNIXコマンドのパイプのように、関数の戻り値を次々とパイプでつないで次の関数に渡している様子が分かるだろうか。
このように |> 演算子を使うと処理が行われる順に関数呼び出しをつないでいけるので、非常に読みやすい。また、カッコが何重にもネストされることもない。
この記法は特に日本人には向いているんじゃないだろうか。英語は 動詞 → 目的語 の語順が自然だが、日本語では 目的語 → 動詞 の語順が自然だ。|> 演算子は日本語的な 目的語 → 動詞 の語順を実現するので、日本人には馴染みやすいのではないかと思う。