2011-08-21 18 views
13

Sanırım aklımı Func'ları anlamaya çalışıyordum ... Bu bir anlam ifade etmiyorsa, özür diliyorum, şu anda bana mantıklı geliyor ama uzun bir gündü. (bazı mantığa dayalı bir boolFunc'ye Dönüştürme <T, String> - Func <T, bool>

Func<T, string> 

bir T aldığımız bir fonksiyon dönüştürmüyoruz Can ve döndürür: Eğer T alır ve bir dizge çıktılar bir fonk verilir varsayarsak

1) Bu durumda döndürülen dize boşsa (String.IsNullOrWhiteSpace)?

Bir

Expression<Func<T, string>> 

verilen ve döndürülen dize ise dayanan doğru/yanlış döndüren bir

Func<T, bool> 

dönüştürmek gerekir eğer

2) Aynı şeyi yapabilir boş (String.IsNullOrWhiteSpace)?

Teşekkür

cevap

11

ilk bölümü için ile,



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

Burada


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

çok basit bir testtir:


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

Eğer Func üzerindeki uzantısı olarak bu tanımlarsanızdaha da kolay olur

(C# tip tip çıkarsama burada çalışıyor umut) İkincisi için: Bence ifadeyi "gerçek" bir Func içine derleyebilir ve sonra yukarıdaki kodu kullanabilirsiniz. see MSDN Docs on Expression.Compile

Not: daha iyi yeni bir işlev oluşturmak 2 fonksiyonlarını oluşturmak yani teknik fonksiyonu kompozisyon olarak bilinir birinci kısmı için (o işlevi kompozisyonunu)

+0

Sanırım "tür çakışması" kastediyorsunuz ve "tür etkileşimi";) –

+0

Teşekkürler! cevaba baktıktan sonra tam anlamıyla geliyor. Birden çok doğru cevap, ancak sizinki ilk ve tamamlanmıştı, böylece çek kontrolünü aldınız. Herkese teşekkürler! – Peter

3

ayrı temsilci olarak tanımlamak alınamadı:



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

kullanım: hatta bazı "yüksek" mertebeden işlevi yapabilir

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

niyetinde olduğunu eşleşecek şekilde işlevini yeniden adlandırıldı. Senin durumunda Eğer fonksiyon kompozisyonu sen Func<T,Bool>

En fonksiyonel programlama dili türde yeni işlevi oluşturmak için şu iki işlev oluşturabilirsiniz kullanarak, tip Func<string,bool> olan bir işlevi Func<T,String> ve (boş dize veya boş gibi) başka bir fonksiyon var Standart kütüphanelerinde ya da dilin kendisinde tanımlanmış olan bu fonksiyon bileşimine sahip olmak. Fakat dil desteklenirse, birinci sınıf değerler olarak işlev görürse, diliniz için bir tane oluşturmak zor değildir.(Bool ve dize Ayrıca parametrize olabilir) Evet:

public static Func<X,Z> Compose<X,Y,Z>(Func<X,Y> a, Func<Y,Z> b) 
{ 
    return (v) => b(a(v)); 
} 
2

1 için:

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

2 için

C# 'sen fonksiyonları oluşturmak sağlayacak aşağıda işlevini kullanabilirsiniz : Evet, ama ilk ifadeyi derlemek gerekir:

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

.Compile ifadesini derleyecek i Döndürülen delege ile çağırabileceğiniz dinamik bir CLR yöntemi. Bu durumda gerçekten yüksek mertebeden fonksiyonunu yazmalıdır, arada

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

:

Böyle bu kodu kullanabilirsiniz. Burada ne yapıyorsunuz (cebirsel olarak), monoileri besteliyor. function composition'u hatırlıyor musunuz? f . g := f(g(x)) burada ne yapıyorsunuz. (A, B ve C kümeleri vardır) f:B->C olarak g:A->B ve harita olarak kaynağın böylece f . g sonuçlarının

Think h:A->C olduğunu. Bu arada, . operatörü sık sık Haskell gibi işlevsel programlama dilleri içine inşa edilir ve compose işlevinizle aynı şeyi elde eder (ancak temiz sözdizimi ile).