<p>这种组合是Python和<code>tools</code>模块都不支持的原始操作(在某种意义上,它不能被分解为其他高阶函数)。你需要自己去实现它。在</p>
<hr/>
<p>缺少的是应用函子的概念(或者更确切地说,Python和<code>tools</code>模块缺少的是应用函子的概念。为了理解<em>这意味着什么,让我们首先回顾一下<code>tools</code>模块中的两个函数:</p>
<ol>
<li><p><code>compose</code>允许您将两个函数链在一起。也就是说</p>
<pre><code>compose(f,g) == lamba x: f(g(x))
</code></pre></li>
<li><p><code>curry</code>与部分应用有关:演示比解释快:</p>
^{pr2}$
<p>也就是说,<code>curry(f)(x)</code>与<code>partial(f, x)</code>基本相同;两者都使用一个值<code>y</code>来返回值<code>f(x, y)</code>。</p></li>
</ol>
<p>此外,<em>函子</em>基本上是一种将函数映射到某个值上的方法。你无疑熟悉列表函子:</p>
<pre><code>map(f, [a,b,c]) == [f(a), f(b), f(c)]
</code></pre>
<p>函数也是<em>也是</em>函子,但是我们使用<code>map</code>,而不是<code>compose</code>。也就是说,将<code>f</code>映射到<code>g</code>上产生{<cd14>}。在</p>
<p>现在,要将<code>mul</code>、<code>f1</code>、和{<cd17>}组合成{<cd18>},似乎{<cd4>}和{<cd5>}都是有用的。也就是说</p>
<pre><code>lambda x: mul(f1(x), f2(x)) == lambda x: curry(mul)(f1(x))(f2(x))
</code></pre>
<p>以及</p>
<pre><code>lambda x: mul(f1(x), f2(x)) == lambda x: compose(curry(mul), f1)(x)(f2(x))
</code></pre>
<p>(也就是说,<code>curry</code>允许我们用另一个函数组合一个双参数函数。)</p>
<p>但从某种意义上讲,复合是严格意义上的线性运算,一个函数的输入来自另一个函数的输出。<code>mul</code>和<code>f1</code>的组合创建一个需要参数的函数,而</em>则返回一个需要相同参数的函数。我们如何将<code>x</code>移出任一表达式的“中间”?我们需要的是
神秘函数<code>foo</code>使得</p>
<pre><code>foo(f, g) = lambda x: f(x, g(x))
</code></pre>
<p>这使得一个函数将其参数传递给<em>同时传递给</em><code>f</code>和{<cd13>},同时还将结果<code>g(x)</code>传递给<code>f</code>。有了这样一个函数<code>foo</code>,我们可以编写</p>
<pre><code>lambda x: foo(compose(curry(mul), f1), f2)
</code></pre>
<p>得到我们想要的结果。在</p>
<p>这就引出了应用函子的概念。{cd25>提供必要的函数</p>
<pre><code>def foo(f, g):
def _(x):
return f(x, g(x))
</code></pre>
<p>它结合了我们目前没有的构图和咖喱的概念。在</p>
<p>换句话说,<code>foo</code>是一个<em>distinct</em>原语操作;您不能根据组合本身来实现它。在</p>