User:Coderjoe/Sandbox2: Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
=={{header| |
=={{header|Nemerle}}== |
||
{{trans|Python}} |
|||
Solution: |
|||
<lang Nemerle>using System; |
|||
<lang groovy>def compose = { f, g -> { x -> f(g(x)) } }</lang> |
|||
using System.Console; |
|||
using System.Math; |
|||
using Nemerle.Collections.NCollectionsExtensions; |
|||
module FirstClassFunc |
|||
Test program: |
|||
{ |
|||
<lang groovy>def cube = { it * it * it } |
|||
Main() : void |
|||
def cubeRoot = { it ** (1/3) } |
|||
{ |
|||
def cube = fun (x) {x * x * x}; |
|||
def croot = fun (x) {Pow(x, 1.0/3.0)}; |
|||
def compose = fun(f, g) {fun (x) {f(g(x))}}; |
|||
def funcs = [Sin, Cos, cube]; |
|||
def ifuncs = [Asin, Acos, croot]; |
|||
WriteLine($[compose(f, g)(0.5) | (f, g) in ZipLazy(funcs, ifuncs)]); |
|||
} |
|||
}</lang> |
|||
=={{header|newLISP}}== |
|||
funcList = [ Math.&sin, Math.&cos, cube ] |
|||
<lang newLISP>> (define (compose f g) (expand (lambda (x) (f (g x))) 'f 'g)) |
|||
inverseList = [ Math.&asin, Math.&acos, cubeRoot ] |
|||
(lambda (f g) (expand (lambda (x) (f (g x))) 'f 'g)) |
|||
> (define (cube x) (pow x 3)) |
|||
(lambda (x) (pow x 3)) |
|||
> (define (cube-root x) (pow x (div 1 3))) |
|||
(lambda (x) (pow x (div 1 3))) |
|||
> (define functions '(sin cos cube)) |
|||
(sin cos cube) |
|||
> (define inverses '(asin acos cube-root)) |
|||
(asin acos cube-root) |
|||
> (map (fn (f g) ((compose f g) 0.5)) functions inverses) |
|||
(0.5 0.5 0.5) |
|||
</lang> |
|||
=={{header|OCaml}}== |
|||
println [funcList, inverseList].transpose().collect { compose(it[0],it[1]) }.collect{ it(0.5) } |
|||
<lang ocaml># let cube x = x ** 3. ;; |
|||
println [inverseList, funcList].transpose().collect { compose(it[0],it[1]) }.collect{ it(0.5) }</lang> |
|||
val cube : float -> float = <fun> |
|||
# let croot x = x ** (1. /. 3.) ;; |
|||
Output: |
|||
val croot : float -> float = <fun> |
|||
<pre>[0.5, 0.4999999999999999, 0.5000000000346574] |
|||
[0.5, 0.4999999999999999, 0.5000000000346574]</pre> |
|||
# let compose f g = fun x -> f (g x) ;; (* we could have written "let compose f g x = f (g x)" but we show this for clarity *) |
|||
=={{header|Haskell}}== |
|||
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun> |
|||
<lang haskell>Prelude> let cube x = x ^ 3 |
|||
Prelude> let croot x = x ** (1/3) |
|||
Prelude> let compose f g = \x -> f (g x) -- this is already implemented in Haskell as the "." operator |
|||
Prelude> -- we could have written "let compose f g x = f (g x)" but we show this for clarity |
|||
Prelude> let funclist = [sin, cos, cube] |
|||
Prelude> let funclisti = [asin, acos, croot] |
|||
Prelude> zipWith (\f inversef -> (compose inversef f) 0.5) funclist funclisti |
|||
[0.5,0.4999999999999999,0.5]</lang> |
|||
# let funclist = [sin; cos; cube] ;; |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
val funclist : (float -> float) list = [<fun>; <fun>; <fun>] |
|||
The Unicon solution can be modified to work in Icon. See [[Function_composition#Icon_and_Unicon]]. |
|||
<lang Unicon>link compose |
|||
procedure main(arglist) |
|||
# let funclisti = [asin; acos; croot] ;; |
|||
fun := [sin,cos,cube] |
|||
val funclisti : (float -> float) list = [<fun>; <fun>; <fun>] |
|||
inv := [asin,acos,cuberoot] |
|||
x := 0.5 |
|||
every i := 1 to *inv do |
|||
write("f(",x,") := ", compose(inv[i],fun[i])(x)) |
|||
end |
|||
# List.map2 (fun f inversef -> (compose inversef f) 0.5) funclist funclisti ;; |
|||
procedure cube(x) |
|||
- : float list = [0.5; 0.499999999999999889; 0.5]</lang> |
|||
return x*x*x |
|||
end |
|||
=={{header|Octave}}== |
|||
procedure cuberoot(x) |
|||
<lang octave>function r = cube(x) |
|||
return x ^ (1./3) |
|||
r = x.^3; |
|||
end</lang> |
|||
endfunction |
|||
Please refer to See [[Function_composition#Icon_and_Unicon]] for 'compose'. |
|||
function r = croot(x) |
|||
Sample Output: |
|||
r = x.^(1/3); |
|||
<pre>f(0.5) := 0.5 |
|||
endfunction |
|||
f(0.5) := 0.4999999999999999 |
|||
f(0.5) := 0.5</pre> |
|||
compose = @(f,g) @(x) f(g(x)); |
|||
=={{header|J}}== |
|||
J has some subtleties which are not addressed in this specification (J functions have grammatical character and their [[wp:Gerund|gerundial form]] may be placed in data structures where the spec sort of implies that there be no such distinction). |
|||
f1 = {@sin, @cos, @cube}; |
|||
However, here are the basics which were requested: |
|||
f2 = {@asin, @acos, @croot}; |
|||
<lang j> sin=: 1&o. |
|||
cos=: 2&o. |
|||
cube=: ^&3 |
|||
square=: *: |
|||
unqo=: `:6 |
|||
unqcol=: `:0 |
|||
quot=: 1 :'{.u`''''' |
|||
A=: sin`cos`cube`square |
|||
B=: monad def'y unqo inv quot'"0 A |
|||
BA=. A dyad def'x unqo@(y unqo) quot'"0 B</lang> |
|||
for i = 1:3 |
|||
<lang> A unqcol 0.5 |
|||
disp(compose(f1{i}, f2{i})(.5)) |
|||
0.479426 0.877583 0.125 0.25 |
|||
endfor</lang> |
|||
BA unqcol 0.5 |
|||
0.5 0.5 0.5 0.5</lang> |
|||
=={{header|Java}}== |
|||
Java doesn't technically have first-class functions. Java can simulate first-class functions to a certain extent, with anonymous classes and generic function interface. |
|||
=={{header|Oz}}== |
|||
<lang java> |
|||
To be executed in the REPL. |
|||
public static Function<Double, Double> compose( |
|||
final Function<Double, Double> f, final Function<Double, Double> g) { |
|||
return new Function<Double, Double>() { |
|||
@Override public Double apply(Double x) { |
|||
return f.apply(g.apply(x)); |
|||
} |
|||
}; |
|||
} |
|||
<lang oz>declare |
|||
@SuppressWarnings("unchecked") public static void main(String[] args) { |
|||
ArrayList<Function<Double, Double>> functions = Lists.newArrayList( |
|||
fun {Compose F G} |
|||
new Function<Double, Double>() { |
|||
fun {$ X} |
|||
@Override public Double apply(Double x) { |
|||
{F {G X}} |
|||
return Math.cos(x); |
|||
end |
|||
} |
|||
end |
|||
}, new Function<Double, Double>() { |
|||
@Override public Double apply(Double x) { |
|||
fun {Cube X} X*X*X end |
|||
return Math.tan(x); |
|||
} |
|||
fun {CubeRoot X} {Number.pow X 1.0/3.0} end |
|||
}, new Function<Double, Double>() { |
|||
@Override public Double apply(Double x) { |
|||
in |
|||
return x * x; |
|||
} |
|||
for |
|||
}); |
|||
F in [Float.sin Float.cos Cube] |
|||
ArrayList<Function<Double, Double>> inverse = Lists.newArrayList( |
|||
I in [Float.asin Float.acos CubeRoot] |
|||
new Function<Double, Double>() { |
|||
do |
|||
@Override public Double apply(Double x) { |
|||
{Show {{Compose I F} 0.5}} |
|||
return Math.acos(x); |
|||
end |
|||
} |
|||
}, new Function<Double, Double>() { |
|||
@Override public Double apply(Double x) { |
|||
return Math.atan(x); |
|||
} |
|||
}, new Function<Double, Double>() { |
|||
@Override public Double apply(Double x) { |
|||
return Math.sqrt(x); |
|||
} |
|||
}); |
|||
for (int i = 0; i < functions.size(); i++) { |
|||
System.out.println(compose(functions.get(i), inverse.get(i)).apply(0.5)); |
|||
} |
|||
} |
|||
</lang> |
</lang> |
||
=={{header|JavaScript}}== |
|||
assuming the print function is provided by the environment, like a stand-alone shell. In browsers, use alert(), document.write() or similar |
|||
=={{header|PARI/GP}}== |
|||
<lang javascript>var compose = function (f, g) { |
|||
{{works with|PARI/GP|2.4.2 and above}} |
|||
return function (x) { |
|||
<lang parigp>compose(f,g)={ |
|||
return f(g(x)); |
|||
x -> f(g(x)) |
|||
}; |
}; |
||
fcf()={ |
|||
var fn = [Math.sin, Math.cos, function (x) { return Math.pow(x, 3); }]; |
|||
my(A,B); |
|||
var inv = [Math.asin, Math.acos, function (x) { return Math.pow(x, 1/3); }]; |
|||
A=[x->sin(x), x->cos(x), x->x^2]; |
|||
B=[x->asin(x), x->acos(x), x->sqrt(x)]; |
|||
for(i=1,#A, |
|||
print(compose(A[i],B[i])(.5)) |
|||
) |
|||
};</lang> |
|||
Usage note: In Pari/GP 2.4.3 the vectors can be written as |
|||
<lang parigp> A=[sin, cos, x->x^2]; |
|||
B=[asin, acos, x->sqrt(x)];</lang> |
|||
=={{header|Perl}}== |
|||
(function () { |
|||
<lang perl>use Math::Complex ':trig'; |
|||
for (var i = 0; i < 3; i++) { |
|||
var f = compose(inv[i], fn[i]); |
|||
print(f(0.5)); // 0.5 |
|||
} |
|||
})(); |
|||
sub compose { |
|||
</lang> |
|||
my ($f, $g) = @_; |
|||
sub { |
|||
$f -> ($g -> (@_)); |
|||
}; |
|||
} |
|||
my $cube = sub { $_[0] ** (3) }; |
|||
=={{header|Lua}}== |
|||
my $croot = sub { $_[0] ** (1/3) }; |
|||
<lang lua> function compose(f,g) return function(...) return f(g(...)) end end |
|||
my @flist1 = ( \&Math::Complex::sin, \&Math::Complex::cos, $cube ); |
|||
fn = {math.sin, math.cos, function(x) return x^3 end} |
|||
my @flist2 = ( \&asin, \&acos, $croot ); |
|||
inv = {math.asin, math.acos, function(x) return x^(1/3) end} |
|||
print join "\n", map { |
|||
for i, v in ipairs(fn) |
|||
compose($flist1[$_], $flist2[$_]) -> (0.5) |
|||
} 0..2;</lang> |
|||
print(f(0.5)) --> 0.5 |
|||
end</lang> |
|||
=={{header| |
=={{header|Perl 6}}== |
||
{{works with|Rakudo|2011.06}} |
|||
The built-in function Composition can do composition, a custom function that does the same would be compose[f_,g_]:=f[g[#]]&. However the latter only works with 2 arguments, Composition works with any number of arguments. |
|||
<lang Mathematica>funcs = {Sin, Cos, #^3 &}; |
|||
<lang perl6>sub compose (&g, &f) { return { g f $^x } } |
|||
funcsi = {ArcSin, ArcCos, #^(1/3) &}; |
|||
compositefuncs = Composition @@@ Transpose[{funcs, funcsi}]; |
|||
my $x = *.sin; |
|||
Table[i[0.666], {i, compositefuncs}]</lang> |
|||
my $xi = *.asin; |
|||
gives back: |
|||
my $y = *.cos; |
|||
<lang Mathematica>{0.666, 0.666, 0.666}</lang> |
|||
my $yi = *.acos; |
|||
Note that I implemented cube and cube-root as pure functions. This shows that Mathematica is fully able to handle functions as variables, functions can return functions, and functions can be given as an argument. Composition can be done in more than 1 way: |
|||
my $z = * ** 3; |
|||
<lang Mathematica>Composition[f,g,h][x] |
|||
my $zi = * ** (1/3); |
|||
f@g@h@x |
|||
x//h//g//f</lang> |
|||
my @functions = $x, $y, $z; |
|||
all give back: |
|||
my @inverses = $xi, $yi, $zi; |
|||
<lang Mathematica>f[g[h[x]]]</lang> |
|||
for @functions Z @inverses { say compose($^g, $^f)(.5) }</lang> |
|||
Output: |
|||
<pre>0.5 |
|||
0.5 |
|||
0.5</pre> |
Revision as of 20:36, 16 July 2011
Nemerle
<lang Nemerle>using System; using System.Console; using System.Math; using Nemerle.Collections.NCollectionsExtensions;
module FirstClassFunc {
Main() : void { def cube = fun (x) {x * x * x}; def croot = fun (x) {Pow(x, 1.0/3.0)}; def compose = fun(f, g) {fun (x) {f(g(x))}}; def funcs = [Sin, Cos, cube]; def ifuncs = [Asin, Acos, croot]; WriteLine($[compose(f, g)(0.5) | (f, g) in ZipLazy(funcs, ifuncs)]); }
}</lang>
newLISP
<lang newLISP>> (define (compose f g) (expand (lambda (x) (f (g x))) 'f 'g)) (lambda (f g) (expand (lambda (x) (f (g x))) 'f 'g)) > (define (cube x) (pow x 3)) (lambda (x) (pow x 3)) > (define (cube-root x) (pow x (div 1 3))) (lambda (x) (pow x (div 1 3))) > (define functions '(sin cos cube)) (sin cos cube) > (define inverses '(asin acos cube-root)) (asin acos cube-root) > (map (fn (f g) ((compose f g) 0.5)) functions inverses) (0.5 0.5 0.5) </lang>
OCaml
<lang ocaml># let cube x = x ** 3. ;; val cube : float -> float = <fun>
- let croot x = x ** (1. /. 3.) ;;
val croot : float -> float = <fun>
- let compose f g = fun x -> f (g x) ;; (* we could have written "let compose f g x = f (g x)" but we show this for clarity *)
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
- let funclist = [sin; cos; cube] ;;
val funclist : (float -> float) list = [<fun>; <fun>; <fun>]
- let funclisti = [asin; acos; croot] ;;
val funclisti : (float -> float) list = [<fun>; <fun>; <fun>]
- List.map2 (fun f inversef -> (compose inversef f) 0.5) funclist funclisti ;;
- : float list = [0.5; 0.499999999999999889; 0.5]</lang>
Octave
<lang octave>function r = cube(x)
r = x.^3;
endfunction
function r = croot(x)
r = x.^(1/3);
endfunction
compose = @(f,g) @(x) f(g(x));
f1 = {@sin, @cos, @cube}; f2 = {@asin, @acos, @croot};
for i = 1:3
disp(compose(f1{i}, f2{i})(.5))
endfor</lang>
Oz
To be executed in the REPL.
<lang oz>declare
fun {Compose F G} fun {$ X} {F {G X}} end end
fun {Cube X} X*X*X end
fun {CubeRoot X} {Number.pow X 1.0/3.0} end
in
for F in [Float.sin Float.cos Cube] I in [Float.asin Float.acos CubeRoot] do {Show {{Compose I F} 0.5}} end
</lang>
PARI/GP
<lang parigp>compose(f,g)={
x -> f(g(x))
};
fcf()={
my(A,B); A=[x->sin(x), x->cos(x), x->x^2]; B=[x->asin(x), x->acos(x), x->sqrt(x)]; for(i=1,#A, print(compose(A[i],B[i])(.5)) )
};</lang> Usage note: In Pari/GP 2.4.3 the vectors can be written as <lang parigp> A=[sin, cos, x->x^2];
B=[asin, acos, x->sqrt(x)];</lang>
Perl
<lang perl>use Math::Complex ':trig';
sub compose {
my ($f, $g) = @_; sub { $f -> ($g -> (@_)); };
}
my $cube = sub { $_[0] ** (3) }; my $croot = sub { $_[0] ** (1/3) };
my @flist1 = ( \&Math::Complex::sin, \&Math::Complex::cos, $cube ); my @flist2 = ( \&asin, \&acos, $croot );
print join "\n", map {
compose($flist1[$_], $flist2[$_]) -> (0.5)
} 0..2;</lang>
Perl 6
<lang perl6>sub compose (&g, &f) { return { g f $^x } }
my $x = *.sin; my $xi = *.asin; my $y = *.cos; my $yi = *.acos; my $z = * ** 3; my $zi = * ** (1/3);
my @functions = $x, $y, $z; my @inverses = $xi, $yi, $zi;
for @functions Z @inverses { say compose($^g, $^f)(.5) }</lang> Output:
0.5 0.5 0.5