関数型プログラミングは、数学における関数の概念を模倣した宣言的なプログラミングパラダイムであり、その中核を成すのが「純粋関数(Pure Function)」である。純粋関数は、同じ入力に対して常に同じ出力を返し、副作用を持たないという特性を持つ。
このような関数型の考え方に基づき、「高階関数(Higher-Order Function)」という重要な概念が存在する。高階関数とは、他の関数を引数として受け取る、または関数を返す関数のことを指す。これは数学における高階関数と直接対応しており、関数型プログラミングの柔軟性と表現力を高める鍵となる。
C# では、デリゲートやラムダ式を用いることで高階関数を自然に実装できる。例えば、LINQ の
Where や
Select といった拡張メソッドは、関数(デリゲート)を引数に取り、新たなシーケンスを返す典型的な高階関数である。
string[] items = { "apple", "banana", "cherry", "date" };
var result = items
.Where(s => s.Contains('a'))
.OrderBy(s => s.Length)
.Select(s => s.ToUpper());
foreach (var item in result) Console.WriteLine(item);
上記コードでは、各メソッドがラムダ式(つまり匿名関数)を受け取り、それを内部で適用している。これにより、データ変換のロジックを宣言的に記述できる。
さらに、関数を返す高階関数も自作可能である。例えば、微分を近似計算する関数を以下のように定義できる:
public delegate double UnaryFunction(double x);
public UnaryFunction Derivative(UnaryFunction f)
{
const double h = 1e-10;
return x => (f(x + h) - f(x)) / h;
}
この
Derivative メソッドは、ある関数
f を受け取り、その導関数(近似)を表す新しい関数を返す。これにより、任意の関数の傾きを動的に取得することが可能になる。
さらに一歩進めて、特定の点における接線の方程式を生成する高階関数も実装できる:
private UnaryFunction TangentLine(double slope, double x0, double y0)
{
double intercept = y0 - slope * x0;
return x => slope * x + intercept;
}
このように、関数を引数に取り、あるいは関数を返すことで、再利用性が高く、数学的直感に基づいたコードを構築できる。これらのテクニックを組み合わせることで、例えば任意の関数のグラフとその接線を描画するアプリケーションを実現することも可能である。