ラムダ式の概要
ラムダ式とは、「ラムダ計算論」を元に、プログラミングの「式」として落とし込んだものになります。ラムダ計算という名前の「ラムダ」は、関数を表現する式に文字ラムダ(= λ)を使う慣習から来ています。
プログラミングのラムダ式を紹介する前に、まずは計算理論としてのラムダ式について簡単に紹介します。これは、F#に限らずC#などの言語でも急にラムダ式の構文や使い方の説明から入っている参考書等が多いですが、いきなり今まで使っていた関数とは異なる記述法を示されても覚えずらいと考えたためです。
中学校くらいで習う代数学を思い出してみましょう。例えば、ある数に2を足す 関数f を考えます。これは通常、
f(x) = x + 2
と書くことができます。この 関数f の 引数x に5を渡すと7が返され、10を渡すと12が返されてきます。関数fをラムダ式で表現では、
λx. x + 2
と記述します。複数の引数を取る関数の場合は以下のようになります。
λx (λy. x + y)
ラムダ計算では、関数の引数は常に1つです。上記のサンプルのように引数を2つとるような関数の場合は、1つの引数を取り、残りの引数と返り値はすべて関数扱いとなります。感の良い方は気づいたかもしれませんが、ラムダ計算では常に カリー化 されています。こういった理論に基づいて関数型プログラミング言語はデザインされているため、C#などの後付けてラムダ式を導入している言語に比べ、理論に近いコードをより簡易に記述することができるわけです。ここで前述した「ある数に2を足す 関数f」とF#のラムダ式とを比較してみます。
ラムダ式 : λx. x + 2
F♯ラムダ式 : fun x -> x + 2
こうやって見比べてみると、非常に単純ですね。「λ が fun」に、「. が ->」に、変わっているだけです。また、複数の引数を取る関数の場合は以下のようになります。
ラムダ式 : λx. λy. x + y
F♯ラムダ式 : fun x -> fun y -> x + y
おそらく、皆さんの予想通りの形だったと思います。しかし、ここで思い出してください。F#の関数は基本的にカリー化されるのでした。つまり、以下のように短縮して記述することも可能です。
fun x y -> x + y
だいぶスッキリしました。このように見た目も機能美も、美しくなるようにF#はデザインされているわけです。そして、プログラミング言語にとって重要な話として、F#のラムダ式は(当たり前ですが)「式」として扱われます。「文」とは違い、値を記述できる箇所であればどこにでも記述可能です。つまり、F#においてラムダ式は非常に多くの場面で活躍できるというわけです。それを念頭に学習を進めましょう。最後にF#のラムダ式の構文を紹介しておきます。
// ------------------
// [ 構文 ]
// ------------------
fun parameter-list -> expression
サンプルでみるラムダ式
ラムダ式は匿名関数とも呼ばれ、F#においては高階関数とともによく使われます。これはわざわざ関数を作成するまでもない場合に特に便利です。
以下に簡単にその違いを表したサンプルを示します。
上記のサンプルのように簡単な条件判定をするためだけに isEven関数 のような関数を作成するのは面倒です。特に関数名を考えることが厳しくなってきます。サンプルではfilterを1度だけしているだけなのであまりそうは感じないかもしれませんが、パイプラインで複数のfilter処理やmap処理を組み合わせていく場合に、それが露見し始めます。また、一つ一つに関数名をつけていくと関数名のレパートリーが尽きていきます。そういったときにラムダ式が活躍するわけですね。
ラムダ式は、F#コーディングにおいて非常重要な機能の一つです。使えないとお話にもならないので、いろいろ試してみて使いこなせるようになりましょう。