This is an experiment to see how far FunctoidsInCpp can be taken to meet the needs discussed in ContinuationPassingStyleInCppQuadraticEquationExample. In particular, it demonstrates nested implementation of objects of type Fun0<T> which have no arguments and return type T. -- JohnFletcher
void message( )
{
std::cout << "message" << std::endl;
},
Fun0<void> messagefun()
{
return ptr_to_fun(&message);
},
Fun0<Fun0<void> > messagefunfun()
{
return ptr_to_fun(&messagefun);
},
Fun0<Fun0<Fun0<void> > > messagefunfunfun()
{
return ptr_to_fun(&messagefunfun);
},
template <typename F>
F callF(const Fun0<F>& f)
{
return f();
},
template <typename F>
F callFrec(const Fun0<F>& f)
{
// I want to make this recursive but I need a test for
// when to stop. Try a specialisation.
return callFrec(f());
},
template <>
void callFrec(const Fun0<void>& f)
{
return f();
},
template <typename F>
F callFull(const Full0<Fun0<F> >& f)
{
return f();
},
int experiments()
{
LambdaVar<1> F;
Fun0<void> messageF = ptr_to_fun(&message);
Fun0<Fun0<void> > messageFF = ptr_to_fun(&messagefun);
Fun0<Fun0<Fun0<void> > > messageFFF = ptr_to_fun(&messagefunfun);
Fun0<Fun0<Fun0<Fun0<void> > > > messageFFFF = ptr_to_fun(&messagefunfunfun);
messageF();
messageFF()();
messageFFF()()();
messageFFFF()()()();
std::cout << "----" << std::endl;
callF(messageF);
callF(callF(messageFF));
callF(callF(callF(messageFFF)));
callF(callF(callF(callF(messageFFFF))));
std::cout << "----" << std::endl;
callFrec(messageF);
// callFrec(messageFF); // won't compile
std::cout << "----" << std::endl;
Full0<Fun0<void> > fullmessageF = makeFull0(messageF);
Full0<Fun0<Fun0<void> > > fullmessageFF = makeFull0(messageFF);
Full0<Fun0<Fun0<Fun0<void> > > > fullmessageFFF = makeFull0(messageFFF);
Full0<Fun0<Fun0<Fun0<Fun0<void> > > > > fullmessageFFFF = makeFull0(messageFFFF);
fullmessageF();
fullmessageFF()();
fullmessageFFF()()();
fullmessageFFFF()()()();
std::cout << "----" << std::endl;
callFull(fullmessageF);
callF(callFull(fullmessageFF));
callF(callF(callFull(fullmessageFFF)));
callF(callF(callF(callFull(fullmessageFFFF))));
std::cout << "----" << std::endl;
lambda(F) [ F[_*_] ] (messageF);
lambda(F) [ F[_*_][_*_] ] (messageFF);
lambda(F) [ F[_*_][_*_][_*_] ] (messageFFF);
lambda(F) [ F[_*_][_*_][_*_][_*_] ] (messageFFFF);
std::cout << "----" << std::endl;
lambda(F) [ F[_*_] ] (fullmessageF);
lambda(F) [ F[_*_][_*_] ] (fullmessageFF);
lambda(F) [ F[_*_][_*_][_*_] ] (fullmessageFFF);
lambda(F) [ F[_*_][_*_][_*_][_*_] ] (fullmessageFFFF);
return 0;
},
Notes:
[_*_] is a fix from FC++ to call a functoid with no arguments, as [ ] fails.
The recursive call callFrec does not work. I need to test for the end condition.
CategoryCpp CategoryFunctionalProgramming