C ++中的定点组合器

时间:2020-03-06 14:54:41  来源:igfitidea点击:

我对使用定点组合器(例如C ++中的y-combinator)的实际示例感兴趣。我们是否曾经在鸡蛋中使用定点组合器或者在实时代码中绑定?

我发现鸡蛋中的这个例子有点稠密:

void egg_example()
{
    using bll::_1;
    using bll::_2;

    int r =
        fix2(
            bll::ret<int>(
                // \(f,a) -> a == 0 ? 1 : a * f(a-1)
                bll::if_then_else_return( _2 == 0,
                    1,
                    _2 * lazy(_1)(_2 - 1)
                )
            )
        ) (5);

    BOOST_CHECK(r == 5*4*3*2*1);
}

我们能解释一下这一切如何运作吗?

有没有一个很好的简单示例,也许使用bind的依赖关系可能比此依赖关系少?

解决方案

这是转换成boost :: bind的相同代码,注意y-combinator及其在主要功能中的应用位置。我希望这有帮助。

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

// Y-combinator compatible factorial
int fact(boost::function<int(int)> f,int v)
{
  if(v == 0)
    return 1;
  else
    return v * f(v -1);
}

// Y-combinator for the int type
boost::function<int(int)>
    y(boost::function<int(boost::function<int(int)>,int)> f)
{
  return boost::bind(f,boost::bind(&y,f),_1);
}

int main(int argc,char** argv)
{
  boost::function<int(int)> factorial = y(fact);
  std::cout << factorial(5) << std::endl;
  return 0;
}

Can you explain how this all works?

fix2是y组合器(具体地说,它是具有两个参数的函数的组合器;第一个参数是函数(出于递归目的),第二个参数是"适当的"函数参数)。它创建递归函数。

bll :: ret(...)似乎可以创建某种形式的函数对象,其主体为

if(second arg == 0)
{
    return 1;
}
else
{
    return second arg * first arg(second arg - 1);
}

"懒惰"可能在那里停止了第一个(函数)自变量的无限扩展(阅读懒惰和严格y组合器之间的区别以了解原因)。

该代码是非常可怕的。匿名函数很不错,但是要解决C ++缺乏语法支持的不足,就不值得使用这些匿名函数。