This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,12 @@
A language has [[wp:First-class function|first-class functions]] if it can do each of the following without recursively invoking a compiler or interpreter or otherwise [[metaprogramming]]:
* Create new functions from preexisting functions at run-time
* Store functions in collections
* Use functions as arguments to other functions
* Use functions as return values of other functions
Write a program to create an ordered collection ''A'' of functions of a real number. At least one function should be built-in and at least one should be user-defined; try using the sine, cosine, and cubing functions. Fill another collection ''B'' with the inverse of each function in ''A''. Implement function composition as in [[Functional Composition]]. Finally, demonstrate that the result of applying the composition of each function in ''A'' and its inverse in ''B'' to a value, is the original value. <small>(Within the limits of computational accuracy)</small>.
(A solution need not actually call the collections "A" and "B". These names are only used in the preceding paragraph for clarity.)
C.f. [[First-class Numbers]]

View file

@ -0,0 +1,2 @@
---
note: Programming language concepts

View file

@ -0,0 +1,25 @@
MODE F = PROC (REAL)REAL;
OP ** = (REAL x, power)REAL: exp(ln(x)*power);
# Add a user defined function and its inverse #
PROC cube = (REAL x)REAL: x * x * x;
PROC cube root = (REAL x)REAL: x ** (1/3);
# First class functions allow run-time creation of functions from functions #
# return function compose(f,g)(x) == f(g(x)) #
PROC non standard compose = (F f1, f2)F: (REAL x)REAL: f1(f2(x)); # eg ELLA ALGOL 68RS #
PROC compose = (F f, g)F: ((F f2, g2, REAL x)REAL: f2(g2(x)))(f, g, );
# Or the classic "o" functional operator #
PRIO O = 5;
OP (F,F)F O = compose;
# first class functions should be able to be members of collection types #
[]F func list = (sin, cos, cube);
[]F arc func list = (arc sin, arc cos, cube root);
# Apply functions from lists as easily as integers #
FOR index TO UPB func list DO
STRUCT(F f, inverse f) this := (func list[index], arc func list[index]);
print(((inverse f OF this O f OF this)(.5), new line))
OD

View file

@ -0,0 +1,11 @@
function compose(f:Function, g:Function):Function {
return function(x:Number) {return f(g(x));};
}
var functions:Array = [Math.cos, Math.tan, function(x:Number){return x*x;}];
var inverse:Array = [Math.acos, Math.atan, function(x:Number){return Math.sqrt(x);}];
function test() {
for (var i:uint = 0; i < functions.length; i++) {
trace(compose(functions[i], inverse[i])(0.5));
}
}

View file

@ -0,0 +1,56 @@
with Ada.Float_Text_IO,
Ada.Integer_Text_IO,
Ada.Text_IO,
Ada.Numerics.Elementary_Functions;
procedure First_Class_Functions is
use Ada.Float_Text_IO,
Ada.Integer_Text_IO,
Ada.Text_IO,
Ada.Numerics.Elementary_Functions;
function Sqr (X : Float) return Float is
begin
return X ** 2;
end Sqr;
type A_Function is access function (X : Float) return Float;
generic
F, G : A_Function;
function Compose (X : Float) return Float;
function Compose (X : Float) return Float is
begin
return F (G (X));
end Compose;
Functions : array (Positive range <>) of A_Function := (Sin'Access,
Cos'Access,
Sqr'Access);
Inverses : array (Positive range <>) of A_Function := (Arcsin'Access,
Arccos'Access,
Sqrt'Access);
begin
for I in Functions'Range loop
declare
function Identity is new Compose (Functions (I), Inverses (I));
Test_Value : Float := 0.5;
Result : Float;
begin
Result := Identity (Test_Value);
if Result = Test_Value then
Put ("Example ");
Put (I, Width => 0);
Put_Line (" is perfect for the given test value.");
else
Put ("Example ");
Put (I, Width => 0);
Put (" is off by");
Put (abs (Result - Test_Value));
Put_Line (" for the given test value.");
end if;
end;
end loop;
end First_Class_Functions;

View file

@ -0,0 +1,13 @@
import math
function compose (f, g) {
return function (x) { return f(g(x)) }
}
var fn = [Math.sin, Math.cos, function(x) { return x*x*x }]
var inv = [Math.asin, Math.acos, function(x) { return Math.pow(x, 1.0/3) }]
for (var i=0; i<3; i++) {
var f = compose(inv[i], fn[i])
println(f(0.5)) // 0.5
}

View file

@ -0,0 +1,31 @@
forward := "sin,cube,cos"
inverse := "Asin,cuberoot,Acos"
StringSplit, forward, forward, `, ; store array length in forward0
StringSplit, inverse, inverse, `, ; array contents are in inverse1, inverse2...
Loop, % forward0
MsgBox % map(compose(forward%A_Index%, inverse%A_Index%), 0.500)
Return
compose(f, g){
Return map(0, 0, f, g)
}
map(ab = 0, x = 0 , a = 0, b = 0)
{
Static
If (a And b)
Return a . "`n" . b
If ab
{
StringSplit, ab, ab, `n
Return %ab1%(%ab2%(x))
}
}
cube(x){
Return x ** 3
}
cuberoot(x){
Return x ** (1 / 3)
}

View file

@ -0,0 +1,3 @@
fns := [sin$Float, cos$Float, (x:Float):Float +-> x^3]
inv := [asin$Float, acos$Float, (x:Float):Float +-> x^(1/3)]
[(f*g) 0.5 for f in fns for g in inv]

View file

@ -0,0 +1,7 @@
)abbrev package TESTP TestPackage
TestPackage(T:SetCategory) : with
_*: (List((T->T)),List((T->T))) -> (T -> List T)
== add
import MappingPackage3(T,T,T)
fs * gs ==
((x:T):(List T) +-> [(f*g) x for f in fs for g in gs])

View file

@ -0,0 +1 @@
(fns * inv) 0.5

View file

@ -0,0 +1 @@
[0.5,0.5,0.5]

View file

@ -0,0 +1,34 @@
REM Create some functions and their inverses:
DEF FNsin(a) = SIN(a)
DEF FNasn(a) = ASN(a)
DEF FNcos(a) = COS(a)
DEF FNacs(a) = ACS(a)
DEF FNcube(a) = a^3
DEF FNroot(a) = a^(1/3)
dummy = FNsin(1)
REM Create the collections (here structures are used):
DIM cA{Sin%, Cos%, Cube%}
DIM cB{Asn%, Acs%, Root%}
cA.Sin% = ^FNsin() : cA.Cos% = ^FNcos() : cA.Cube% = ^FNcube()
cB.Asn% = ^FNasn() : cB.Acs% = ^FNacs() : cB.Root% = ^FNroot()
REM Create some function compositions:
AsnSin% = FNcompose(cB.Asn%, cA.Sin%)
AcsCos% = FNcompose(cB.Acs%, cA.Cos%)
RootCube% = FNcompose(cB.Root%, cA.Cube%)
REM Test applying the compositions:
x = 1.234567 : PRINT x, FN(AsnSin%)(x)
x = 2.345678 : PRINT x, FN(AcsCos%)(x)
x = 3.456789 : PRINT x, FN(RootCube%)(x)
END
DEF FNcompose(f%,g%)
LOCAL f$, p%
f$ = "(x)=" + CHR$&A4 + "(&" + STR$~f% + ")(" + \
\ CHR$&A4 + "(&" + STR$~g% + ")(x))"
DIM p% LEN(f$) + 4
$(p%+4) = f$ : !p% = p%+4
= p%

View file

@ -0,0 +1,26 @@
double acos (double d) { return Math.acos(d); }
double asin (double d) { return Math.asin(d); }
double cos (double d) { return Math.cos(d); }
double sin (double d) { return Math.sin(d); }
double croot (double d) { return Math.pow(d, 1/3); }
double cube (double x) { return x * x * x; }
Var compose (Var f, Var g, double x)
{
Func ff = f;
Func fg = g;
return ff(fg(x));
}
void button1_onClick (Widget widget)
{
Array arr1 = [ sin, cos, cube ];
Array arr2 = [ asin, acos, croot ];
str s;
for (int i = 1; i <= 3; i++)
{
s << compose(arr1.get(i), arr2.get(i), 0.5) << str.newline;
}
label1.setText(s);
}

View file

@ -0,0 +1,3 @@
0.5
0.4999999999999999
0.5000000000000001

View file

@ -0,0 +1,38 @@
#include <functional>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
using std::cout;
using std::endl;
using std::vector;
using std::function;
using std::transform;
using std::back_inserter;
typedef function<double(double)> FunType;
vector<FunType> A = {sin, cos, tan, [](double x) { return x*x*x; } };
vector<FunType> B = {asin, acos, atan, [](double x) { return exp(log(x)/3); } };
template <typename A, typename B, typename C>
function<C(A)> compose(function<C(B)> f, function<B(A)> g) {
return [f,g](A x) { return f(g(x)); };
}
int main() {
vector<FunType> composedFuns;
auto exNums = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0};
transform(B.begin(), B.end(),
A.begin(),
back_inserter(composedFuns),
compose<double, double, double>);
for (auto num: exNums)
for (auto fun: composedFuns)
cout << u8"f\u207B\u00B9.f(" << num << ") = " << fun(num) << endl;
return 0;
}

View file

@ -0,0 +1,72 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/* declare a typedef for a function pointer */
typedef double (*Class2Func)(double);
/*A couple of functions with the above prototype */
double functionA( double v)
{
return v*v*v;
}
double functionB(double v)
{
return exp(log(v)/3);
}
/* A function taking a function as an argument */
double Function1( Class2Func f2, double val )
{
return f2(val);
}
/*A function returning a function */
Class2Func WhichFunc( int idx)
{
return (idx < 4) ? &functionA : &functionB;
}
/* A list of functions */
Class2Func funcListA[] = {&functionA, &sin, &cos, &tan };
Class2Func funcListB[] = {&functionB, &asin, &acos, &atan };
/* Composing Functions */
double InvokeComposed( Class2Func f1, Class2Func f2, double val )
{
return f1(f2(val));
}
typedef struct sComposition {
Class2Func f1;
Class2Func f2;
} *Composition;
Composition Compose( Class2Func f1, Class2Func f2)
{
Composition comp = malloc(sizeof(struct sComposition));
comp->f1 = f1;
comp->f2 = f2;
return comp;
}
double CallComposed( Composition comp, double val )
{
return comp->f1( comp->f2(val) );
}
/** * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main(int argc, char *argv[])
{
int ix;
Composition c;
printf("Function1(functionA, 3.0) = %f\n", Function1(WhichFunc(0), 3.0));
for (ix=0; ix<4; ix++) {
c = Compose(funcListA[ix], funcListB[ix]);
printf("Compostion %d(0.9) = %f\n", ix, CallComposed(c, 0.9));
}
return 0;
}

View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef double (*f_dbl)(double);
#define TAGF (f_dbl)0xdeadbeef
#define TAGG (f_dbl)0xbaddecaf
double dummy(double x)
{
f_dbl f = TAGF;
f_dbl g = TAGG;
return f(g(x));
}
f_dbl composite(f_dbl f, f_dbl g)
{
size_t len = (void*)composite - (void*)dummy;
f_dbl ret = malloc(len);
char *ptr;
memcpy(ret, dummy, len);
for (ptr = (char*)ret; ptr < (char*)ret + len - sizeof(f_dbl); ptr++) {
if (*(f_dbl*)ptr == TAGF) *(f_dbl*)ptr = f;
else if (*(f_dbl*)ptr == TAGG) *(f_dbl*)ptr = g;
}
return ret;
}
double cube(double x)
{
return x * x * x;
}
/* uncomment next line if your math.h doesn't have cbrt() */
/* double cbrt(double x) { return pow(x, 1/3.); } */
int main()
{
int i;
double x;
f_dbl A[3] = { cube, exp, sin };
f_dbl B[3] = { cbrt, log, asin}; /* not sure about availablity of cbrt() */
f_dbl C[3];
for (i = 0; i < 3; i++)
C[i] = composite(A[i], B[i]);
for (i = 0; i < 3; i++) {
for (x = .2; x <= 1; x += .2)
printf("C%d(%g) = %g\n", i, x, C[i](x));
printf("\n");
}
return 0;
}

View file

@ -0,0 +1,17 @@
C0(0.2) = 0.2
C0(0.4) = 0.4
C0(0.6) = 0.6
C0(0.8) = 0.8
C0(1) = 1
C1(0.2) = 0.2
C1(0.4) = 0.4
C1(0.6) = 0.6
C1(0.8) = 0.8
C1(1) = 1
C2(0.2) = 0.2
C2(0.4) = 0.4
C2(0.6) = 0.6
C2(0.8) = 0.8
C2(1) = 1

View file

@ -0,0 +1,4 @@
(use 'clojure.contrib.math)
(let [fns [#(Math/sin %) #(Math/cos %) (fn [x] (* x x x))]
inv [#(Math/asin %) #(Math/acos %) #(expt % 1/3)]]
(map #(% 0.5) (map #(comp %1 %2) fns inv)))

View file

@ -0,0 +1,13 @@
# Functions as values of a variable
cube = (x) -> Math.pow x, 3
cuberoot = (x) -> Math.pow x, 1 / 3
# Higher order function
compose = (f, g) -> (x) -> f g(x)
# Storing functions in a array
fun = [Math.sin, Math.cos, cube]
inv = [Math.asin, Math.acos, cuberoot]
# Applying the composition to 0.5
console.log compose(inv[i], fun[i])(0.5) for i in [0..2]

View file

@ -0,0 +1,13 @@
(defun compose (f g) (lambda (x) (funcall f (funcall g x))))
(defun cube (x) (expt x 3))
(defun cube-root (x) (expt x (/ 3)))
(loop with value = 0.5
for function in (list #'sin #'cos #'cube )
for inverse in (list #'asin #'acos #'cube-root)
for composed = (compose inverse function)
do (format t "~&(~A ∘ ~A)(~A) = ~A~%"
inverse
function
value
(funcall composed value)))

View file

@ -0,0 +1,3 @@
(#<FUNCTION ASIN> #<FUNCTION SIN>)(0.5) = 0.5
(#<FUNCTION ACOS> #<FUNCTION COS>)(0.5) = 0.5
(#<FUNCTION CUBE-ROOT> #<FUNCTION CUBE>)(0.5) = 0.5

View file

@ -0,0 +1,16 @@
import std.stdio, std.math, std.typetuple, std.functional;
enum sin = (in real x) => std.math.sin(x),
asin = (in real x) => std.math.asin(x),
cos = (in real x) => std.math.cos(x),
acos = (in real x) => std.math.acos(x),
cube = (in real x) => x ^^ 3,
cbrt = (in real x) => std.math.cbrt(x);
void main() {
alias TypeTuple!(sin, cos, cube) dir;
alias TypeTuple!(asin, acos, cbrt) inv;
foreach (i, f; dir) {
writefln("%6.3f", compose!(f, inv[i])(0.5));
}
}

View file

@ -0,0 +1,18 @@
T delegate(S) compose(T, U, S)(in T function(in U) f,
in U function(in S) g) {
return s => f(g(s));
}
void main() {
import std.stdio, std.math, std.range;
immutable sin = (in real x) => sin(x),
asin = (in real x) => asin(x),
cos = (in real x) => cos(x),
acos = (in real x) => acos(x),
cube = (in real x) => x ^^ 3,
cbrt = (in real x) => cbrt(x);
foreach (f, g; zip([sin, cos, cube], [asin, acos, cbrt]))
writefln("%6.3f", compose(f, g)(0.5));
}

View file

@ -0,0 +1,13 @@
cube(x) { return x * x * x; }
inv_cube(x) { return Math.pow(x, 1/3); }
compo(f1, f2) {
return func(x) { return f1(f2(x));};
}
main() {
var funcs = [Math.sin, Math.exp, cube];
var invs = [Math.asin, Math.log, inv_cube];
for (int i = 0; i < 3; i++)
print(compo(funcs[i], invs[i])(1));
}

View file

@ -0,0 +1,9 @@
def sin(x) { return x.sin() }
def cos(x) { return x.cos() }
def asin(x) { return x.asin() }
def acos(x) { return x.acos() }
def cube(x) { return x ** 3 }
def curt(x) { return x ** (1/3) }
def forward := [sin, cos, cube]
def reverse := [asin, acos, curt]

View file

@ -0,0 +1,3 @@
def compose(f, g) {
return fn x { f(g(x)) }
}

View file

@ -0,0 +1,9 @@
? def x := 0.5 \
> for i => f in forward {
> def g := reverse[i]
> println(`x = $x, f = $f, g = $g, compose($f, $g)($x) = ${compose(f, g)(x)}`)
> }
x = 0.5, f = <sin>, g = <asin>, compose(<sin>, <asin>)(0.5) = 0.5
x = 0.5, f = <cos>, g = <acos>, compose(<cos>, <acos>)(0.5) = 0.4999999999999999
x = 0.5, f = <cube>, g = <curt>, compose(<cube>, <curt>)(0.5) = 0.5000000000000001

View file

@ -0,0 +1,10 @@
open number //sin,cos,asin,acos
open list //zipWith
cube x = x ** 3
croot x = x ** (1/3)
funclist = [sin, cos, cube]
funclisti = [asin, acos, croot]
zipWith (\f inversef -> (inversef << f) 0.5) funclist funclisti

View file

@ -0,0 +1 @@
(<<) f g x = f (g x)

View file

@ -0,0 +1 @@
[0.5,0.5,0.499999989671302]

View file

@ -0,0 +1,10 @@
USING: assocs combinators kernel math.functions prettyprint
sequences ;
IN: rosettacode.first-class-functions
CONSTANT: A { [ sin ] [ cos ] [ 3 ^ ] }
CONSTANT: B { [ asin ] [ acos ] [ 1/3 ^ ] }
: compose-all ( seq1 seq2 -- seq ) [ compose ] 2map ;
: test1 ( -- )
0.5 A B compose-all
[ call( x -- y ) ] with map . ;

View file

@ -0,0 +1,19 @@
class FirstClassFns
{
static |Obj -> Obj| compose (|Obj -> Obj| fn1, |Obj -> Obj| fn2)
{
return |Obj x -> Obj| { fn2 (fn1 (x)) }
}
public static Void main ()
{
cube := |Float a -> Float| { a * a * a }
cbrt := |Float a -> Float| { a.pow(1/3f) }
|Float->Float|[] fns := [Float#sin.func, Float#cos.func, cube]
|Float->Float|[] inv := [Float#asin.func, Float#acos.func, cbrt]
|Float->Float|[] composed := fns.map |fn, i| { compose(fn, inv[i]) }
composed.each |fn| { echo (fn(0.5f)) }
}
}

View file

@ -0,0 +1,22 @@
: compose ( xt1 xt2 -- xt3 )
>r >r :noname
r> compile,
r> compile,
postpone ;
;
: cube fdup fdup f* f* ;
: cuberoot 1e 3e f/ f** ;
: table create does> swap cells + @ ;
table fn ' fsin , ' fcos , ' cube ,
table inverse ' fasin , ' facos , ' cuberoot ,
: main
3 0 do
i fn i inverse compose ( xt )
0.5e execute f.
loop ;
main \ 0.5 0.5 0.5

View file

@ -0,0 +1,36 @@
# Function composition
Composition := function(f, g)
local h;
h := function(x)
return f(g(x));
end;
return h;
end;
# Apply each function in list u, to argument x
ApplyList := function(u, x)
local i, n, v;
n := Size(u);
v := [ ];
for i in [1 .. n] do
v[i] := u[i](x);
od;
return v;
end;
# Inverse and Sqrt are in the built-in library. Note that GAP doesn't have real numbers nor floating point numbers. Therefore, Sqrt yields values in cyclotomic fields.
# For example,
# gap> Sqrt(7);
# E(28)^3-E(28)^11-E(28)^15+E(28)^19-E(28)^23+E(28)^27
# where E(n) is a primitive n-th root of unity
a := [ i -> i + 1, Inverse, Sqrt ];
# [ function( i ) ... end, <Operation "InverseImmutable">, <Operation "Sqrt"> ]
b := [ i -> i - 1, Inverse, x -> x*x ];
# [ function( i ) ... end, <Operation "InverseImmutable">, function( x ) ... end ]
# Compose each couple
z := ListN(a, b, Composition);
# Now a test
ApplyList(z, 3);
[ 3, 3, 3 ]

View file

@ -0,0 +1,27 @@
package main
import "math"
import "fmt"
// user-defined function, per task. Other math functions used are built-in.
func cube(x float64) float64 { return math.Pow(x, 3) }
// ffType and compose function taken from Function composition task
type ffType func(float64) float64
func compose(f, g ffType) ffType {
return func(x float64) float64 {
return f(g(x))
}
}
func main() {
// collection A
funclist := []ffType{math.Sin, math.Cos, cube}
// collection B
funclisti := []ffType{math.Asin, math.Acos, math.Cbrt}
for i := 0; i < 3; i++ {
// apply composition and show result
fmt.Println(compose(funclisti[i], funclist[i])(.5))
}
}

View file

@ -0,0 +1 @@
def compose = { f, g -> { x -> f(g(x)) } }

View file

@ -0,0 +1,8 @@
def cube = { it * it * it }
def cubeRoot = { it ** (1/3) }
funcList = [ Math.&sin, Math.&cos, cube ]
inverseList = [ Math.&asin, Math.&acos, cubeRoot ]
println [funcList, inverseList].transpose().collect { compose(it[0],it[1]) }.collect{ it(0.5) }
println [inverseList, funcList].transpose().collect { compose(it[0],it[1]) }.collect{ it(0.5) }

View file

@ -0,0 +1,8 @@
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]

View file

@ -0,0 +1,17 @@
link compose
procedure main(arglist)
fun := [sin,cos,cube]
inv := [asin,acos,cuberoot]
x := 0.5
every i := 1 to *inv do
write("f(",x,") := ", compose(inv[i],fun[i])(x))
end
procedure cube(x)
return x*x*x
end
procedure cuberoot(x)
return x ^ (1./3)
end

View file

@ -0,0 +1,10 @@
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

View file

@ -0,0 +1,4 @@
A unqcol 0.5
0.479426 0.877583 0.125 0.25
BA unqcol 0.5
0.5 0.5 0.5 0.5

View file

@ -0,0 +1,70 @@
import java.util.ArrayList;
public class FirstClass{
public interface Function<A,B>{
B apply(A x);
}
public static <A,B,C> Function<A, C> compose(
final Function<B, C> f, final Function<A, B> g) {
return new Function<A, C>() {
@Override public C apply(A x) {
return f.apply(g.apply(x));
}
};
}
public static void main(String[] args){
ArrayList<Function<Double, Double>> functions =
new ArrayList<Function<Double,Double>>();
functions.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return Math.cos(x);
}
});
functions.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return Math.tan(x);
}
});
functions.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return x * x;
}
});
ArrayList<Function<Double, Double>> inverse = new ArrayList<Function<Double,Double>>();
inverse.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return Math.acos(x);
}
});
inverse.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return Math.atan(x);
}
});
inverse.add(
new Function<Double, Double>(){
@Override public Double apply(Double x){
return Math.sqrt(x);
}
});
System.out.println("Compositions:");
for(int i = 0; i < functions.size(); i++){
System.out.println(compose(functions.get(i), inverse.get(i)).apply(0.5));
}
System.out.println("Hard-coded compositions:");
System.out.println(Math.cos(Math.acos(0.5)));
System.out.println(Math.tan(Math.atan(0.5)));
System.out.println(Math.pow(Math.sqrt(0.5), 2));
}
}

View file

@ -0,0 +1,36 @@
import java.util.ArrayList;
import java.util.function.Function;
public class FirstClass{
public static <A,B,C> Function<A, C> compose(
final Function<B, C> f, final Function<A, B> g) {
return new Function<A, C>() {
@Override public C apply(A x) {
return f.apply(g.apply(x));
}
};
}
public static void main(String[] args){
ArrayList<Function<Double, Double>> functions = new ArrayList<>();
functions.add(Math::cos);
functions.add(Math::tan);
functions.add(x -> x * x);
ArrayList<Function<Double, Double>> inverse = new ArrayList<>();
inverse.add(Math::acos);
inverse.add(Math::atan);
inverse.add(Math::sqrt);
System.out.println("Compositions:");
for(int i = 0; i < functions.size(); i++){
System.out.println(compose(functions.get(i), inverse.get(i)).apply(0.5));
}
System.out.println("Hard-coded compositions:");
System.out.println(Math.cos(Math.acos(0.5)));
System.out.println(Math.tan(Math.atan(0.5)));
System.out.println(Math.pow(Math.sqrt(0.5), 2));
}
}

View file

@ -0,0 +1,23 @@
// Functions as values of a variable
var cube = function(x) {
return Math.pow(x, 3);
};
var cuberoot = function(x) {
return Math.pow(x, 1/3);
};
// Higher order function
var compose = function (f, g) {
return function (x) {
return f(g(x));
};
};
// Storing functions in a array
var fun = [Math.sin, Math.cos, cube];
var inv = [Math.asin, Math.acos, cuberoot];
for (var i = 0; i < 3; i++) {
// Applying the composition to 0.5
console.log(compose(inv[i], fun[i])(0.5));
}

View file

@ -0,0 +1,9 @@
function compose(f,g) return function(...) return f(g(...)) end end
fn = {math.sin, math.cos, function(x) return x^3 end}
inv = {math.asin, math.acos, function(x) return x^(1/3) end}
for i, v in ipairs(fn) do
local f = compose(v, inv[i])
print(f(0.5))
end

View file

@ -0,0 +1,3 @@
0.5
0.5
0.5

View file

@ -0,0 +1,7 @@
> A := [ sin, cos, x -> x^3 ]:
> B := [ arcsin, arccos, rcurry( surd, 3 ) ]:
> zip( `@`, A, B )( 2/3 );
[2/3, 2/3, 2/3]
> zip( `@`, B, A )( 2/3 );
[2/3, 2/3, 2/3]

View file

@ -0,0 +1,4 @@
funcs = {Sin, Cos, #^3 &};
funcsi = {ArcSin, ArcCos, #^(1/3) &};
compositefuncs = Composition @@@ Transpose[{funcs, funcsi}];
Table[i[0.666], {i, compositefuncs}]

View file

@ -0,0 +1 @@
{0.666, 0.666, 0.666}

View file

@ -0,0 +1,3 @@
Composition[f,g,h][x]
f@g@h@x
x//h//g//f

View file

@ -0,0 +1 @@
f[g[h[x]]]

View file

@ -0,0 +1,5 @@
a: [sin, cos, lambda([x], x^3)]$
b: [asin, acos, lambda([x], x^(1/3))]$
compose(f, g) := buildq([f, g], lambda([x], f(g(x))))$
map(lambda([fun], fun(x)), map(compose, a, b));
[x, x, x]

View file

@ -0,0 +1,17 @@
:- module firstclass.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module exception, list, math, std_util.
main(!IO) :-
Forward = [sin, cos, (func(X) = ln(X))],
Reverse = [asin, acos, (func(X) = exp(X))],
Results = map_corresponding(
(func(F, R) = compose(R, F, 0.5)),
Forward, Reverse),
write_list(Results, ", ", write_float, !IO),
write_string("\n", !IO).

View file

@ -0,0 +1,13 @@
$compose = function ($f, $g) {
return function ($x) use ($f, $g) {
return $f($g($x));
};
};
$fn = array('sin', 'cos', function ($x) { return pow($x, 3); });
$inv = array('asin', 'acos', function ($x) { return pow($x, 1/3); });
for ($i = 0; $i < 3; $i++) {
$f = $compose($inv[$i], $fn[$i]);
echo $f(0.5), PHP_EOL;
}

View file

@ -0,0 +1,19 @@
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;

View file

@ -0,0 +1,17 @@
(load "@lib/math.l")
(de compose (F G)
(curry (F G) (X)
(F (G X)) ) )
(de cube (X)
(pow X 3.0) )
(de cubeRoot (X)
(pow X 0.3333333) )
(mapc
'((Fun Inv)
(prinl (format ((compose Inv Fun) 0.5) *Scl)) )
'(sin cos cube)
'(asin acos cubeRoot) )

View file

@ -0,0 +1,24 @@
:- use_module(library(lambda)).
compose(F,G, FG) :-
FG = \X^Z^(call(G,X,Y), call(F,Y,Z)).
cube(X, Y) :-
Y is X ** 3.
cube_root(X, Y) :-
Y is X ** (1/3).
first_class :-
L = [sin, cos, cube],
IL = [asin, acos, cube_root],
% we create the composed functions
maplist(compose, L, IL, Lst),
% we call the functions
maplist(call, Lst, [0.5,0.5,0.5], R),
% we display the results
maplist(writeln, R).

View file

@ -0,0 +1,15 @@
>>> # Some built in functions and their inverses
>>> from math import sin, cos, acos, asin
>>> # Add a user defined function and its inverse
>>> cube = lambda x: x * x * x
>>> croot = lambda x: x ** (1/3.0)
>>> # First class functions allow run-time creation of functions from functions
>>> # return function compose(f,g)(x) == f(g(x))
>>> compose = lambda f1, f2: ( lambda x: f1(f2(x)) )
>>> # first class functions should be able to be members of collection types
>>> funclist = [sin, cos, cube]
>>> funclisti = [asin, acos, croot]
>>> # Apply functions from lists as easily as integers
>>> [compose(inversef, f)(.5) for f, inversef in zip(funclist, funclisti)]
[0.5, 0.4999999999999999, 0.5]
>>>

View file

@ -0,0 +1,10 @@
cube <- function(x) x^3
croot <- function(x) x^(1/3)
compose <- function(f, g) function(x){f(g(x))}
f1 <- c(sin, cos, cube)
f2 <- c(asin, acos, croot)
for(i in 1:3) {
print(compose(f1[[i]], f2[[i]])(.5))
}

View file

@ -0,0 +1 @@
sapply(mapply(compose,f1,f2),do.call,list(.5))

View file

@ -0,0 +1,10 @@
#lang racket
(define (compose f g) (λ (x) (f (g x))))
(define (cube x) (expt x 3))
(define (cube-root x) (expt x (/ 1 3)))
(define funlist (list sin cos cube))
(define ifunlist (list asin acos cube-root))
(for ([f funlist] [i ifunlist])
(displayln ((compose i f) 0.5)))

View file

@ -0,0 +1,12 @@
irb(main):001:0> cube = proc{|x| x ** 3}
=> #<Proc:0x0000020c66b878@(irb):1>
irb(main):002:0> croot = proc{|x| x ** (1.quo 3)}
=> #<Proc:0x00000201f6a6c8@(irb):2>
irb(main):003:0> compose = proc {|f,g| proc {|x| f[g[x]]}}
=> #<Proc:0x00000205e4e768@(irb):3>
irb(main):004:0> funclist = [Math.method(:sin), Math.method(:cos), cube]
=> [#<Method: Math.sin>, #<Method: Math.cos>, #<Proc:0x0000020c66b878@(irb):1>]
irb(main):005:0> invlist = [Math.method(:asin), Math.method(:acos), croot]
=> [#<Method: Math.asin>, #<Method: Math.acos>, #<Proc:0x00000201f6a6c8@(irb):2>]
irb(main):006:0> funclist.zip(invlist).map {|f, invf| compose[invf, f][0.5]}
=> [0.5, 0.4999999999999999, 0.5]

View file

@ -0,0 +1,18 @@
import math._
// functions as values
val cube = (x: Double) => x * x * x
val cuberoot = (x: Double) => pow(x, 1 / 3d)
// higher order function, as a method
def compose[A,B,C](f: B => C, g: A => B) = (x: A) => f(g(x))
// partially applied functions in Lists
val fun = List(sin _, cos _, cube)
val inv = List(asin _, acos _, cuberoot)
// composing functions from the above Lists
val comp = (fun, inv).zipped map (_ compose _)
// output results of applying the functions
comp foreach {f => print(f(0.5) + " ")}

View file

@ -0,0 +1,7 @@
class SweetFunction[B,C](f: B => C) {
def o[A](g: A => B) = (x: A) => f(g(x))
}
implicit def sugarOnTop[A,B](f: A => B) = new SweetFunction(f)
// now functions can be composed thus
println((cube o cube o cuberoot)(0.5))

View file

@ -0,0 +1,16 @@
(define (compose f g) (lambda (x) (f (g x))))
(define (cube x) (expt x 3))
(define (cube-root x) (expt x (/ 1 3)))
(define function (list sin cos cube))
(define inverse (list asin acos cube-root))
(define x 0.5)
(define (go f g)
(if (not (or (null? f)
(null? g)))
(begin (display ((compose (car f) (car g)) x))
(newline)
(go (cdr f) (cdr g)))))
(go function inverse)

View file

@ -0,0 +1,23 @@
|forward reverse composer compounds|
"commodities"
Number extend [
cube [ ^self raisedTo: 3 ]
].
Number extend [
cubeRoot [ ^self raisedTo: (1 / 3) ]
].
forward := #( #cos #sin #cube ).
reverse := #( #arcCos #arcSin #cubeRoot ).
composer := [ :f :g | [ :x | f value: (g value: x) ] ].
"let us create composed funcs"
compounds := OrderedCollection new.
1 to: 3 do: [ :i |
compounds add: ([ :j | composer value: [ :x | x perform: (forward at: j) ]
value: [ :x | x perform: (reverse at: j) ] ] value: i)
].
compounds do: [ :r | (r value: 0.5) displayNl ].

View file

@ -0,0 +1,17 @@
% namespace path tcl::mathfunc ;# to import functions like abs() etc.
% proc cube x {expr {$x**3}}
% proc croot x {expr {$x**(1/3.)}}
% proc compose {f g} {list apply {{f g x} {{*}$f [{*}$g $x]}} $f $g}
% compose abs cube ;# returns a partial command, without argument
apply {{f g x} {{*}$f [{*}$g $x]}} abs cube
% {*}[compose abs cube] -3 ;# applies the partial command to argument -3
27
% set forward [compose [compose sin cos] cube] ;# omitting to print result
% set backward [compose croot [compose acos asin]]
% {*}$forward 0.5
0.8372297964617733
% {*}$backward [{*}$forward 0.5]
0.5000000000000017