2011-08-21 242 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功能(但有更清晰的语法)。

相关问题