14

Funcs を理解しようとして頭が爆発していると思います... これが意味をなさない場合は、申し訳ありません。

1) T を受け取り、文字列を出力する func が与えられたと仮定します。

 Func<T, string> 

これを、T を受け取り、ロジックに基づいて bool を返す func に変換できますか (この場合、返された文字列が空 (String.IsNullOrWhiteSpace) の場合)?

 Func<T, bool> 

2) 与えられた場合、同じことができますか?

Expression<Func<T, string>>

そしてそれをに変換する必要があります

Func<T, bool>

返された文字列が空 (String.IsNullOrWhiteSpace) であるかどうかに基づいて true/false を返しますか?

ありがとう

4

4 に答える 4

11

最初の部分では、「高次」関数を作成することもできます。



Func<A,C> MapFun<A,B,C>(Func<A,B> input, Func<B,C> transf)
{
   return a => transf(input(a));
}

で使用



Func <T,string> test = ...
var result = MapFun(test, String.IsNullOrWhiteSpace);

(ここで C# の型推論が機能することを願っています)

これを Func の拡張として定義すると、さらに簡単になります。


public static class FuncExtension
{
    public static Func<A,C> ComposeWith<A,B,C>(this Func<A,B> input, Func<B,C> f)
    {
         return a => f(input(a));
    }
}

ここに非常に簡単なテストがあります:


Func<int, string> test = i => i.ToString();
var result = test.ComposeWith(string.IsNullOrEmpty);

2 つ目: 式を「実際の」 Func にコンパイルしてから、上記のコードを使用できると思います。Expression.Compile に関する MSDN ドキュメントを参照してください。

PS:意図に合わせて関数の名前を変更しました(関数の構成です)

于 2011-08-21T12:19:13.510 に答える
3

別のデリゲートとして定義できませんでした:

Func<T, string> func1 = t => t.ToString();
Func<T, bool> func2 = t => string.IsNullOrEmpty(func1(t));
于 2011-08-21T12:18:40.923 に答える
2

最初の部分では、この手法は関数合成として知られています。つまり、2つの関数を合成して、新しい関数を作成します。あなたの場合、関数Func<T,String>とタイプの別の関数(文字列が空またはnullなど)がありFunc<string,bool>ます。関数の合成を使用して、これら2つの関数を合成し、タイプの新しい関数を作成できます。Func<T,Bool>

ほとんどの関数型プログラミング言語には、標準ライブラリまたは言語自体ですでに定義されているこの関数の合成があります。ただし、言語がファーストクラスの値として関数をサポートしている場合は、その言語用に作成するのは難しくありません。

C#では、以下の関数を使用して、関数を作成できます。

public static Func<X,Z> Compose<X,Y,Z>(Func<X,Y> a, Func<Y,Z> b)
{
    return (v) => b(a(v));
}
于 2011-08-21T12:32:30.110 に答える
2

1:はい(boolとstringをパラメーター化することもできます):

Func<T, bool> Compose<T>(Func<T, string> source, Func<string, bool>map)
{
    return x => map(source(x));
}

To 2:はい。ただし、最初に式をコンパイルする必要があります。

Func<T, bool> Compose<T>(Expression<Func<T, string>> source, Func<string, bool> map)
{
    return x => compose(source.Compile(), map)
}

.Compile式を動的CLRメソッドにコンパイルし、返されたデリゲートで呼び出すことができます。

このコードは次のように使用できます。

Func<int, string> ts = i => i.ToString();
var result = Compose(ts, string.IsNullOrEmpty);

ちなみに、この場合は実際に高階関数を書く必要があります。ここで(代数的に)行っているのは、モノイドの作成です。関数の合成を覚えていますか?f . g := f(g(x))あなたがここでしていることです。

ソースをとしてg:A->B、マップをf:B->C(A、B、Cがセットである)と考えると、の結果はf . gですh:A->C。ちなみに、.演算子はHaskellなどの関数型プログラミング言語に組み込まれていることが多く、関数と同じことを実現しますcompose(ただし、構文はよりクリーンです)。

于 2011-08-21T12:33:18.580 に答える