C++ 在C+中实现和包装函数组合+;用于延迟评估

C++ 在C+中实现和包装函数组合+;用于延迟评估,c++,functional-programming,template-meta-programming,C++,Functional Programming,Template Meta Programming,假设我有一个applicative的简单实现,这是我为保持理智而选择的一个名称,而不是因为我从其他语言中了解applicative类型类。执行情况如下: #include <iostream> #include <string> template <typename T> struct applicative { template <typename Fn> auto then(Fn f) const { retu

假设我有一个
applicative
的简单实现,这是我为保持理智而选择的一个名称,而不是因为我从其他语言中了解
applicative
类型类。执行情况如下:

#include <iostream>
#include <string>

template <typename T>
struct applicative {
    template <typename Fn>
    auto then(Fn f) const {
        return applicative<decltype(f(data_))>{f(data_)};
    } 

    template <typename Fn>
    auto and_last(Fn f) const {
        return f(data_);
    }
    T data_;
};

int main() {
    applicative<std::string>{"hello world"}
    .then([](std::string const& s) {return s.size() * 4; })
    .then([](int k) {return k - 2; })
    .and_last([](int k) { std::cout << k << "\n"; });
} 
很好。回到我的想法,我认为这应该可以通过以下方式对我的
应用程序实现进行返工:

auto sf = applicative<std::string>{}
    .then([](std::string const& s) {return s.size() * 4; })
    .then([](int k) {return k - 2; });

    std::cout << sf.eval_with("hello world"); << "\n"; 
这些
然后
调用将导致一个相当于
(s.size()*4)-2的函数调用,可以用
eval_与
进行计算,这是您想要的吗

#include <iostream>
#include <string>

struct id
{
    template <typename T>
    auto operator()(T t) const
    {
        return t;
    }
};

template <typename T, typename Func = id>
struct applicative {
    applicative(Func f = Func())
        : _f(f)
    {
    }

    template <typename Fn>
    auto then(Fn f) const {
        auto composition = [=](T val) { return f(_f(val)); };
        return applicative<T, decltype(composition)>(composition);
    } 

    auto eval_with(T t)
    {
        return _f(t);
    }

    Func _f;
};

int main() {
    auto sf = applicative<std::string>{}
    .then([](std::string const& s) {return s.size() * 4; })
    .then([](int k) {return k - 2; });

    std::cout << sf.eval_with("hello world") << "\n"; 
} 
#包括
#包括
结构id
{
模板
自动运算符()(T)常量
{
返回t;
}
};
模板
结构应用程序{
applicative(Func f=Func())
:_f(f)
{
}
模板
自动然后(Fn f)常数{
自动合成=[=](T val){返回f(_f(val));};
返回应用程序(组合);
} 
带(T)的自动评估
{
返回f(t);
}
函数(f),;
};
int main(){
自动sf=应用程序{}
.then([](std::string const&s){return s.size()*4;})
。然后([](int k){返回k-2;});

你有什么想法?你总是需要调用所有的函数,要么急切地(第一种情况),要么懒惰地(第二种情况)你的目标相当于一个咖喱
组合
@Caleth鉴于
std::bind
,我认为如果涉及咖喱,它不会像我想要的那样高效?你可以先看看boost::lambda和boost::yap。基本上,我有发明身份函数的想法,但无法让它工作。通过一些完美的转发,我可以你可以把这个问题简化为一个额外的步骤,将参数从
eval_with
传递到第一个
然后是
调用。谢谢。你有没有可能也知道这个东西是否对应于任何类别理论类型类?是否可以将它传递到
Functor
applicative<std::string>{"hello world"}
    .then([](std::string const& s) {return s.size() * 4; })
    .then([](int k) {return k - 2; })
    .and_last([](int k) { std::cout << k << "\n"; });
#include <iostream>
#include <string>

struct id
{
    template <typename T>
    auto operator()(T t) const
    {
        return t;
    }
};

template <typename T, typename Func = id>
struct applicative {
    applicative(Func f = Func())
        : _f(f)
    {
    }

    template <typename Fn>
    auto then(Fn f) const {
        auto composition = [=](T val) { return f(_f(val)); };
        return applicative<T, decltype(composition)>(composition);
    } 

    auto eval_with(T t)
    {
        return _f(t);
    }

    Func _f;
};

int main() {
    auto sf = applicative<std::string>{}
    .then([](std::string const& s) {return s.size() * 4; })
    .then([](int k) {return k - 2; });

    std::cout << sf.eval_with("hello world") << "\n"; 
}