2011-08-21 130 views
13

我想我的腦海正在爆炸,試圖找出Funcs ......如果這沒有意義,我很抱歉,現在它對我有意義,但已經過了漫長的一天......將Func <T, String>轉換成Func <T, bool>

1)假設你被給予FUNC這需要在T和輸出一個字符串:

Func<T, string> 

你能變換成採取以T一個FUNC並返回基於某些邏輯一個bool(在這種情況下,如果返回的字符串是空的(String.IsNullOrWhiteSpace)?

Func<T, bool> 

2)你可以做同樣的事情,如果你將得到一個

Expression<Func<T, string>> 

,並需要將其轉換爲

Func<T, bool> 

,基於如果返回的字符串返回真/假空(String.IsNullOrWhiteSpace)?

感謝

回答

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#類型類型推斷這裏工作)

如果你定義了這個擴展的函數功能它變得更簡單:


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); 

對於第二個:我認爲你可以將表達式編譯成一個「真實」的Func,然後使用上面的代碼。 see MSDN Docs on Expression.Compile

PS:改名功能以更好地匹配它的打算(它的功能的組合物)

+0

我猜你的意思是「類型推斷」,而不是「類型的干擾」;) –

+0

謝謝!在你看完答案後,這是完全合理的。多個正確的答案,但你的是第一個完整的,所以你得到檢查檢查。謝謝大家! – Peter

3

你能不能把它定義爲一個單獨的委託:

Func<T, string> func1 = t => t.ToString(); 
Func<T, bool> func2 = t => string.IsNullOrEmpty(func1(t)); 
2

對於技術被稱爲功能組合物的第一部分即撰寫2個函數來創建一個新的功能。 你的情況,你有一個函數Func<T,String>和另一個函數(如字符串爲空或null),這是Func<string,bool>型的,使用功能組成,你可以撰寫這兩個函數創建類型的新功能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)); 
} 
2

爲1:是(你也可以參數化布爾和字符串):

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

爲2 :是的,但你需要編譯表達式第一:

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

.Compile將編譯表達我n要,您可以用返回的委託調用動態CLR方法。

您可以使用此代碼:

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

順便說一句,在這種情況下,你應該寫一個高階函數。你在這裏(代數)在做什麼是組成monoids。請記住function compositionf . g := f(g(x))是你在這裏做什麼。

源作爲g:A->B和圖作爲​​(其中,A,B和C是一組),以的f . g結果認爲h:A->C。順便說一句,在.運營商往往是建設成函數式編程語言,如Haskell和達到同樣的事情,你compose功能(但有更清晰的語法)。

相關問題