Function composition: Difference between revisions
(added java) |
(first attempt at c, what do you guys think?) |
||
Line 30: | Line 30: | ||
+.500000000000000e +0 +.500000000000000e +0 |
+.500000000000000e +0 +.500000000000000e +0 |
||
</pre> |
</pre> |
||
=={{header|C}}== |
|||
Only works for functions taking a double and returning a double: |
|||
<lang c>#include <stdlib.h> |
|||
/* generic interface for functors from double to double */ |
|||
typedef struct double_to_double { |
|||
double (*fn)(struct double_to_double *, double); |
|||
} double_to_double; |
|||
#define CALL(f, x) f->fn(f, x) |
|||
/* functor returned by compose */ |
|||
typedef struct compose_functor { |
|||
double (*fn)(struct compose_functor *, double); |
|||
double_to_double *f; |
|||
double_to_double *g; |
|||
} compose_functor; |
|||
/* function to be used in "fn" in preceding functor */ |
|||
double compose_call(compose_functor *this, double x) { |
|||
return CALL(this->f, CALL(this->g, x)); |
|||
} |
|||
/* returns functor that is the composition of functors |
|||
f & g. caller is responsible for deallocating memory */ |
|||
double_to_double *compose(double_to_double *f, |
|||
double_to_double *g) { |
|||
compose_functor *result = malloc(sizeof(compose_functor)); |
|||
result->fn = &compose_call; |
|||
result->f = f; |
|||
result->g = g; |
|||
return (double_to_double *)result; |
|||
} |
|||
#include <math.h> |
|||
/* we can make functors for sin and asin by using |
|||
the following as "fn" in a functor */ |
|||
double sin_call(double_to_double *this, double x) { |
|||
return sin(x); |
|||
} |
|||
double asin_call(double_to_double *this, double x) { |
|||
return asin(x); |
|||
} |
|||
#include <stdio.h> |
|||
int main() { |
|||
double_to_double *my_sin = malloc(sizeof(double_to_double)); |
|||
my_sin->fn = &sin_call; |
|||
double_to_double *my_asin = malloc(sizeof(double_to_double)); |
|||
my_asin->fn = &asin_call; |
|||
double_to_double *sin_asin = compose(my_sin, my_asin); |
|||
printf("%f\n", CALL(sin_asin, 0.5)); /* prints "0.500000" */ |
|||
free(sin_asin); |
|||
free(my_sin); |
|||
free(my_asin); |
|||
return 0; |
|||
}</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
Revision as of 22:55, 4 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
Hint: Implementing compose correctly requires creating a closure. If your language does not support closures directly, you will need to implement it yourself.
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
Only works for functions taking a double and returning a double: <lang c>#include <stdlib.h>
/* generic interface for functors from double to double */ typedef struct double_to_double {
double (*fn)(struct double_to_double *, double);
} double_to_double;
- define CALL(f, x) f->fn(f, x)
/* functor returned by compose */
typedef struct compose_functor {
double (*fn)(struct compose_functor *, double); double_to_double *f; double_to_double *g;
} compose_functor; /* function to be used in "fn" in preceding functor */ double compose_call(compose_functor *this, double x) {
return CALL(this->f, CALL(this->g, x));
} /* returns functor that is the composition of functors
f & g. caller is responsible for deallocating memory */
double_to_double *compose(double_to_double *f,
double_to_double *g) { compose_functor *result = malloc(sizeof(compose_functor)); result->fn = &compose_call; result->f = f; result->g = g; return (double_to_double *)result;
}
- include <math.h>
/* we can make functors for sin and asin by using
the following as "fn" in a functor */
double sin_call(double_to_double *this, double x) {
return sin(x);
} double asin_call(double_to_double *this, double x) {
return asin(x);
}
- include <stdio.h>
int main() {
double_to_double *my_sin = malloc(sizeof(double_to_double)); my_sin->fn = &sin_call; double_to_double *my_asin = malloc(sizeof(double_to_double)); my_asin->fn = &asin_call;
double_to_double *sin_asin = compose(my_sin, my_asin);
printf("%f\n", CALL(sin_asin, 0.5)); /* prints "0.500000" */
free(sin_asin); free(my_sin); free(my_asin);
return 0;
}</lang>
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>
Common Lisp
<lang lisp>(defun compose (f g) (lambda (x) (funcall f (funcall g x))))</lang> Example use: <lang lisp>>(defun compose (f g) (lambda (x) (funcall f (funcall g x)))) COMPOSE >(let ((sin-asin (compose #'sin #'asin))))
(funcall sin-asin 0.5))
0.5</lang>
Haskell
This is already defined as the . (dot) operator in Haskell. <lang haskell>compose f g x = f (g x)</lang> Example use: <lang haskell>Prelude> let compose f g x = f (g x) Prelude> let sin_asin = compose sin asin Prelude> sin_asin 0.5 0.5</lang>
Java
<lang java>public class Compose {
// Java doesn't have function type so we define an interface // of function objects instead public interface Fun<A,B> { B call(A x); }
public static <A,B,C> Fun<A,C> compose(final Fun<B,C> f, final Fun<A,B> g) { return new Fun<A,C>() { public C call(A x) { return f.call(g.call(x)); } }; }
public static void main(String[] args) { Fun<Double,Double> sin = new Fun<Double,Double>() { public Double call(Double x) { return Math.sin(x); } }; Fun<Double,Double> asin = new Fun<Double,Double>() { public Double call(Double x) { return Math.asin(x); } };
Fun<Double,Double> sin_asin = compose(sin, asin);
System.out.println(sin_asin.call(0.5)); // prints "0.5" }
}</lang>
JavaScript
<lang javascript>
function compose(f, g) { return function(x) { return f(g(x)) } }
var id = compose(Math.sin, Math.asin) print id(0.5) // 0.5
</lang>
Joy
Composition is the default operation in Joy. The composition of two functions is the concatenation of those functions, in the order in which they are to be applied. <lang joy>
g f
</lang>
OCaml
<lang ocaml>let compose f g x = f (g x)</lang> Example use: <lang ocaml># let compose f g x = f (g x);; val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
- let sin_asin = compose sin asin;;
val sin_asin : float -> float = <fun>
- sin_asin 0.5;;
- : float = 0.5</lang>
Perl
<lang perl>sub compose
{my ($f, $g) = @_; return sub {$f->($g->(@_))};}
use Math::Trig; print compose(sub {sin $_[0]}, \&asin)->(0.5), "\n";</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>