Convert Func<T, String> to Func<T, bool>

断了今生、忘了曾经 提交于 2020-01-02 00:54:08

问题


I think my mind is exploding trying to figure out Funcs... If this makes no sense, I apologize, right now it make sense to me but its been a long day already ....

1) Assuming you are given a func which takes in T and outputs a string:

 Func<T, string> 

Can you transform that into a func that take in a T and returns a bool based on some logic (in this case if the returned string is empty (String.IsNullOrWhiteSpace)?

 Func<T, bool> 

2) Can you do the same thing if you are given an

Expression<Func<T, string>>

and need to convert it to a

Func<T, bool>

that returns true/false based on if the returned string is empty (String.IsNullOrWhiteSpace)?

Thanks


回答1:


for the first part you can even make some "higher"-order function:



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

use with



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

(I hope C# type type inference is working here)

If you define this as extension on Func it gets even easier:


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

here is a very simple test:


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

For the second one: I think you can compile the expression into a "real" Func and then use the above code. see MSDN Docs on Expression.Compile

PS: renamed the function to better match it's intend (it's function composition)




回答2:


Could you not define it as a separate delegate:

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



回答3:


For the first part the technique is known as function composition i.e you compose 2 functions to create a new function. In your case you have a function Func<T,String> and another function (like string empty or null) which is of type Func<string,bool>, using function composition you can compose these two functions to create a new function of type Func<T,Bool>

Most functional programming language have this composition of function already defined in their standard library or in the language itself. But it is no tough to create one for your language if the language supports functions as first class values.

In C# you can use the below function which will allow you to compose functions:

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



回答4:


To 1: Yes (You can also parametrize bool and string):

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

To 2: Yes, but you need to compile the expression first:

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

.Compile will compile the expression into a dynamic CLR method that you can invoke with the returned delegate.

You can use this code like this:

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

By the way, in this case you should really write a higher-order function. What you are doing here (algebraically) is composing monoids. Remember function composition? f . g := f(g(x)) is what you are doing here.

Think of source as g:A->B and map as f:B->C (where A,B and C are sets) so the result of f . g is h:A->C. By the way, the . operator is often build into functional programming languages, such as Haskell and achieves the same thing as your compose function (but with cleaner syntax).



来源:https://stackoverflow.com/questions/7138182/convert-funct-string-to-funct-bool

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!