Function composition: Difference between revisions
(added c++) |
|||
Line 27: | Line 27: | ||
+.500000000000000e +0 +.500000000000000e +0 |
+.500000000000000e +0 +.500000000000000e +0 |
||
</pre> |
</pre> |
||
=={{header|C++}}== |
|||
Note: this is already implemented as <code>__gnu_cxx::compose1()</code> |
|||
<lang cpp>#include <functional> |
|||
#include <cmath> |
|||
#include <iostream> |
|||
// functor class to be returned by compose function |
|||
template <class Fun1, class Fun2> |
|||
class compose_functor : |
|||
public std::unary_function<typename Fun2::argument_type, |
|||
typename Fun1::result_type> |
|||
{ |
|||
protected: |
|||
Fun1 f; |
|||
Fun2 g; |
|||
public: |
|||
compose_functor(const Fun1& _f, const Fun2& _g) |
|||
: f(_f), g(_g) { } |
|||
typename Fun1::result_type |
|||
operator()(const typename Fun2::argument_type& x) const |
|||
{ return f(g(x)); } |
|||
}; |
|||
// we wrap it in a function so the compiler infers the template arguments |
|||
// whereas if we used the class directly we would have to specify them explicitly |
|||
template <class Fun1, class Fun2> |
|||
inline compose_functor<Fun1, Fun2> |
|||
compose(const Fun1& f, const Fun2& g) |
|||
{ return compose_functor<Fun1,Fun2>(f, g); } |
|||
int main() { |
|||
std::cout << compose(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl; |
|||
return 0; |
|||
}</lang> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python>compose = lambda f, g: lambda x: f( g(x) )</lang> |
<lang python>compose = lambda f, g: lambda x: f( g(x) )</lang> |
Revision as of 11:42, 3 March 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Create a function, compose, whose two arguments f and g, are both functions with one argument. The result of compose is to be a function of one argument, (lets call the argument x), which works like applying function f to the result of applying function g to x.
I.e:
compose(f, g)(x) == f( g(x) )
Reference: Function composition
ALGOL 68
Note: Returning PROC (REAL x)REAL: f1(f2(x))
from a function apparently
violates standard ALGOL 68's scoping rules. ALGOL 68G warns about this during
parsing, and then rejects during runtime.
<lang algol>MODE F = PROC(REAL)REAL; # ALGOL 68 is strong typed #
- As a procedure for real to real functions #
PROC compose = (F f, g)F: (REAL x)REAL: f(g(x));
OP (F,F)F O = compose; # or an OPerator that can be overloaded #
- Example use: #
F sin arc sin = compose(sin, arc sin); print((sin arc sin(0.5), (sin O arc sin)(0.5), new line))</lang> Output:
+.500000000000000e +0 +.500000000000000e +0
C++
Note: this is already implemented as __gnu_cxx::compose1()
<lang cpp>#include <functional>
- include <cmath>
- include <iostream>
// functor class to be returned by compose function template <class Fun1, class Fun2> class compose_functor :
public std::unary_function<typename Fun2::argument_type, typename Fun1::result_type>
{ protected:
Fun1 f; Fun2 g;
public:
compose_functor(const Fun1& _f, const Fun2& _g) : f(_f), g(_g) { }
typename Fun1::result_type operator()(const typename Fun2::argument_type& x) const { return f(g(x)); }
};
// we wrap it in a function so the compiler infers the template arguments // whereas if we used the class directly we would have to specify them explicitly template <class Fun1, class Fun2> inline compose_functor<Fun1, Fun2> compose(const Fun1& f, const Fun2& g) { return compose_functor<Fun1,Fun2>(f, g); }
int main() {
std::cout << compose(std::ptr_fun(::sin), std::ptr_fun(::asin))(0.5) << std::endl;
return 0;
}</lang>
Python
<lang python>compose = lambda f, g: lambda x: f( g(x) )</lang> Example use: <lang python>>>> compose = lambda f, g: lambda x: f( g(x) ) >>> from math import sin, asin >>> sin_asin = compose(sin, asin) >>> sin_asin(0.5) 0.5 >>> </lang>
Scheme
<lang scheme>(define (compose f g) (lambda (x) (f (g x))))</lang> Example use: <lang scheme>> (define (compose f g) (lambda (x) (f (g x)))) > (define sin_asin (compose sin asin)) > (sin_asin 0.5) 0.5</lang>