C#でカリー化する利点は何ですか?
カリー化された関数で部分的な関数の適用を実現する利点は何ですか?
ウィキペディアより
カリー化は、実際には、紙上の特定の値に対して関数を計算するときに行うこととあまり変わりません。
関数を取る
f(x,y) = y / x
を評価するには
f(2,3)
、まず に置き換えx
ます2
。結果は y の新しい関数なので、この関数 g(y) は次のように定義できます。
g(y) = f(2,y) = y / 2
次に、
y
引数をに置き換えて3
、結果 を提供します
g(3) = f(2,3) = 3 / 2
。紙の上では、古典的な表記法を使用すると、すべてを同時に行っているように見えるだけです。しかし、実際には、1 枚の紙の引数を置き換える場合、それは順次 (つまり部分的に) 行われます。各置換は、関数内の関数になります。各引数を順番に置き換えながら、関数を元のより単純なバージョンにカリー化します。最終的には、各関数が 1 つの引数のみを取り、複数の引数を持つ関数は通常、カリー化された形式で表されるラムダ計算のような一連の関数になります。
カリー化の実際的な動機は、カリー化された関数 (部分適用と呼ばれることが多い) にすべての引数ではなく一部の引数を提供することによって得られる関数が役立つことが非常に多いということです。たとえば、多くの言語には、plus_one に似た関数または演算子があります。カリー化すると、これらの関数を簡単に定義できます。
あなたの質問が C# でカリー化を実装する方法だった場合、ここに例があります
public Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> func)
{
return p1 => p2 => func(p1, p2);
}
カリー化は、クロージャー (ラムダ) をサポートする任意の言語で実装でき、関数の実行に必要なすべての入力が受信されない UI プログラミングのような部分関数アプリケーションに役立ちます。したがって、カリー化された関数は、既に受信した入力がキャプチャされた状態で渡されます。初期化。
C# でのカリー化の利点は、C# 開発者が関数型プログラミング スタイルで開発できることです。
LINQ について考えてみましょう。LINQ クエリを使用すると、メソッドをパラメーターとして渡すことができます。
someCollection.Where(x => x.someVal == 1);
x.someVal == 1
関数として評価され、Where
それ自体の実行で戻り値を使用します。
これは、ほとんどの .NET 3 開発者がよく知っている例ですが、関数プログラミングに手を出していることに気付いている人はほとんどいません。Curry の機能がなければ、LINQ は不可能です。
...私の賢いお尻のコメントを補ってくれることを願っています。
簡単なカリー化は次のようになります
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
Func<double, double, double, double, double> newTonLaw = (m1, m2, r, g) => ((m1 * m2) / Math.Pow(r,2)) * g;
// Mass of Earth= 5.98 * 10e24 , Gravitational Constant = 6.6726 * 10e-11
Func<double, double, double> onEarth = (m2, r) => newTonLaw.Invoke(5.98 * 10e24, m2, r, 6.6726*10e-11);
// Mass of Moon= 7.348x10e22 , Gravitational Constant = 6.6726 * 10e-11
Func<double, double, double> onMoon = (m2, r) => newTonLaw.Invoke(7.348 * 10e22, m2, r, 6.6726 * 10e-11);
Trace.WriteLine(onEarth(70, 6.38 * 10e6)); // result 686.203545562642
Trace.WriteLine(onMoon(70, 6.38 * 10e6)); // result 8.43181212841855
}
}
}