我正在尝试用C ++实现阅读器函子。相应的Haskell定义为fmap :: :( a-> b)->(r-> a)->(r-> b)
我的C ++版本是:
template<class A, class B, class R>
B fmap(const std::function<B(A)> &funcA, const std::function<A(R)> &funcR) {
return funcA(funcR());
}
std::string function_1(int n);
double function_2(std::string s);
fmap(function_2, function_1);
错误是:
note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-0)>' against 'double (std::__1::basic_string<char>)'
B fmap(const std::function<B(A)> &funcA, const std::function<A(R)> &funcR) {
实现fmap函数的正确方法是什么?
#include <functional>
#include <iostream>
#include <string>
using namespace std;
template<class T>
struct AsFunction
: public AsFunction<decltype(&T::operator())>
{};
template<class ReturnType, class... Args>
struct AsFunction<ReturnType(Args...)> {
using type = std::function<ReturnType(Args...)>;
};
template<class ReturnType, class... Args>
struct AsFunction<ReturnType(*)(Args...)> {
using type = std::function<ReturnType(Args...)>;
};
template<class Class, class ReturnType, class... Args>
struct AsFunction<ReturnType(Class::*)(Args...) const> {
using type = std::function<ReturnType(Args...)>;
};
template<class F>
auto toFunction(F f) -> typename AsFunction<F>::type {
return { f };
}
template<class A, class B, class R>
B fmap(const std::function<B(A)>& funcA, const std::function<A(R)>& funcR, R value) {
return funcA(funcR(value));
}
template <class T>
auto ToFunction(T t) {
return t;
}
std::string function_1(int n) {
return ""s;
}
double function_2(std::string s) {
return 0.0;
}
int main() {
fmap(toFunction(function_2), toFunction(function_1), 5);
return 0;
}