【问题标题】:How does this C# function composition method work?这个 C# 函数组合方法是如何工作的?
【发布时间】:2018-03-25 07:34:45
【问题描述】:

我出现了以下代码:

public static class FuncUtils
{
    public static Func<T1, T3> Compose<T1, T2, T3> (Func<T1, T2> f1, Func<T2, T3> f2)
    {
        return a => f2(f1(a));
    }
}

对我来说最大的谜团是这个

返回 a => f2(f1(a));

你能解释一下它是如何工作的吗?

【问题讨论】:

  • 它返回一个接受 a 并返回 f2(f1(a)) 的函数。
  • 这将返回一个新函数,该函数接收参数a,其主体为f2(f1(a))。当调用该函数时,它将在 a 上调​​用 f1,然后在该结果上调用 f2。这就是该方法被称为Compose 的原因。它需要两个函数f1, f2 并返回第三个函数,它在f2 的结果上调用f1
  • 这是一个 lambda 表达式。
  • 我想说有人试图在 F# 中复制 ` >> ` 运算符,它允许您编写 (f1 &gt;&gt; f2)(a)
  • 例如:假设你有一个Func&lt;int, int&gt; add5 = i =&gt; i + 5; 和一个Func&lt;int, int&gt; doubleIt = i =&gt; i * 2; 然后FuncUtils.Compose(add5, doubleIt) 会给你一个函数f 加5然后乘以2,所以f(3) = 16跨度>

标签: c# .net functional-programming func


【解决方案1】:

它将返回一个Func&lt;T1, T3&gt;这是一个函数(委托),它接受T1 类型的一些参数并返回T3 类型的结果。我们调用返回的Funcf

f 的结果(返回值)只是 2 个函数参数 f1f2 组合(如数学函数组合)在任何给定参数上的结果。

更多关于f,返回Func

在参数aT1类型)上应用f1,得到一些结果bT2类型),然后在b上应用f2,调用这个结果@987654338 @(T3 类型)。 c 将是任何 a 传递给 f 的结果。

【讨论】:

    【解决方案2】:

    您需要了解高阶函数的概念才能理解上述方法。高阶函数在 .NET 中被建模为 delegates,因此在 c# 中也是如此。委托是表示要调用的方法的数据类型。所以当你执行你的方法时,你得到的结果是你需要调用的另一个方法来得到你的结果(因此 higher order 函数)。

    让我们来剖析一下你的方法:

    参数Func&lt;T1, T2&gt; f1Func&lt;T2, T3&gt; f2 是委托,每个代表一个方法。您可以通过调用委托来调用这些方法:

    //You need a value of type T1, here represented by the variable a
    T2 value = f1(a);
    

    调用必须如下所示,因为这是委托 id 的定义方式:

    public delegate TResult Func<T, TResult>(T item);
    

    您可以像调用f1 一样调用f2,只是使用不同的参数类型。由于T2f1的返回值和T2的参数,你可以将f1的结果传递给f2

    T2 result = f2(value);
    

    或内联:

    T2 result = f2(f1(a));
    

    你会在你的方法中找到这个,这意味着它执行两个方法的嵌套调用。

    在一个特殊的转折中,Compose 不调用方法并返回结果,它自己返回一个更高阶的函数。它为此使用 lambda 运算符 =&gt;,这是另一种创建委托的方法。 lambda 运算符的左侧是a,它是新函数参数的任意名称。 a的类型是T1,编译器可以通过类型推断来判断。

    所以最终调用者必须执行返回的委托才能获得最终结果。这称为延迟执行,在 LINQ 中很常见。

    您可以将Compose 方法视为一种在实际进行调用之前将调用嵌套到两个方法的方法。

    【讨论】:

      猜你喜欢
      • 2018-07-17
      • 2016-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多