バックグラウンド
私は最近、.NET 4 の System.String クラスに Join メソッドの新しいオーバーロードがあることを読みました。この新しいオーバーロードは区切り記号を取り、IEnumerable<T>
中間の文字列配列に変換する必要なく、任意のコレクションを 1 つの文字列に結合できるようにします。
涼しい!つまり、これを実行できるようになりました。
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0);
var list = string.Join(",",evenNums);
...これの代わりに:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.Select(i => i.ToString())
.ToArray();
var list = string.Join(",", evenNums);
...したがって、すべてのアイテムを文字列に変換してから、配列を割り当てる必要がありません。
問題
ただし、プログラミング全般の関数型スタイルのファンであり、特に C# でのメソッド チェーンのファンである私は、次のようなものを記述できるようにしたいと考えています。
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.string.Join(",");
ただし、これは正当な C# ではありません。はい、私はでそれを行うことEnumerable.Aggregate
ができました、そして、はい、私は独自の Join 拡張メソッドでそれを行うことができました )、しかし、これらのアプローチは読みにくい/非効率的であり、(それぞれ)警官のように感じるので、試してみたいと思いますそれは別の方法です。これまでに得た最も近いものは次のとおりです。
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.ApplyTo(
Functional.Curry<string, IEnumerable<object>, string>
(string.Join)(",")
);
...次の拡張メソッドを使用:
public static class Functional
{
public static TRslt
ApplyTo<TArg, TRslt>(this TArg arg, Func<TArg, TRslt> func)
{
return func(arg);
}
public static Func<T1, Func<T2, TResult>>
Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
{
Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curried
= f => x => y => f(x, y);
return curried(func);
}
}
これは非常に冗長で、引数の 1 つを IEnumerable ではなく IEnumerable として定義しているため、パラメーターと戻り値の型を明示的に定義する必要があります。
チャレンジ
メソッド連鎖スタイルのプログラミングを使用して、これを達成するためのより適切な方法を見つけることができますか?
この課題は、C# で、複数のオーバーロードを持つ関数をカリー化するための簡潔な方法を見つけようとすることです。これはただの楽しみです。