Einfache Kombinatoren

Beschreibung

Folgende Konstruktionen dienen als Grundbausteine für unsere späteren Implementationen. Diese Grundbausteine kommen zum Teil aus dem Lambda Kalkül.

Wichtige Funktionen (Grundbausteine)

id - Die Identitätsfunktion

Die Identitätsfunktion nimmt einen Wert entgegen und gibt diesen wieder zurück.

Implementation:

const id = x => x;

Beispiele:

id(10);           // 10
id(id);           // id
id("Hello");      // "Hello"

Kestrel - Die Konstante Funktion

Die Konstante Funktion nimmt zwei Paramter entgegen und gibt den ersten wieder zurück.

Implementation:

const K = x => y => x;

Beispiele:

K(1)(2);         // 1
K(8)(id);        // 8
K('q')('t');     // 'q'

Kite

Der Kite ist eine Funktion, die zwei Parameter entgegennimmt und den zweiten Parameter zurückgibt.

Implementation:

const KI = x => y => y;

Beispiele:

KI(1)(2);                // 2
KI(id)(3);               // 3
KI("Hello")("World");    // "World"

Mockingbird

Der Mockingbird nimmt einen Funktion entgegen und wendet die Funktion auf sich selber an. (English: self-application)

Implementation:

const M = f => f(f);

Beispiele:

M(id);        // id
M(id)(5);     // 5
M(M);         // stack overflow, da M(M) ==> M(M) ==> M(M) ....

Cardinal (Flip) - Vertauschungsfunktion

Die Vertauschungsfunktion nimmt eine Funktion und zwei Argumente entgegen und wendet die Argumente in vertauschter Reihenfolge auf die übergebene Funktion an.

Implementation:

const C = f => x => y => f(y)(x);

Beispiel:

const diff = x => y => x - y;

C(diff)(2)(3);        //  1
C(diff)(3)(2);        // -1

Bluebird - Funktionskomposition

Der Bluebird nimmt zwei Funktionen und ein Argument entgegen. Zuerst wendet der Bluebird das Argument auf die zweite Funktion an und das Resultat wird auf die erste Funktion angewendet. Der Bluebird funktioniert gleich wie die Funktionskomposition in der Mathematik .

Implementation:

const B = f => g => x => f(g(x));

Beispiele:

    const f = x => x + 1;
    const g = x => x * 2;
    
    B(f)(g)(4);      // 9
    B(g)(f)(4);      // 10
    B(id)(id)(5);    // 5

Thrush

Der Thrush nimmt ein Argument und eine Funktion entgegen. Dieses Argument wendet der Thrush auf die übergebene Funktion an.

Implementation:

const T = x => f => f(x);

Beispiele:

const f = x => x + 1;

T(2)(f);            // 3
T(2)(id);           // 2 

Vireo

Der Vireo ist eine Funktion, die zwei Argumente und eine Funktion entgegen nimmt. Die Funktion wendet die zwei übergebenen Argumente auf die übergebene Funktion an. Der Vireo ist gleichzeitig eine unveränderliche Datenstruktur, siehe Pair.

Implementation:

const V = x => y => f => f(x)(y);

Pair

Das Pair ist eine unveränderliche Datenstruktur bestehend aus zwei Elementen. Mit sogenannten "getter"-Funktionen kann auf diese Werte zugegriffen werden. Für beide Werte des Pairs gibt es eine "getter"-Funktion. Für den ersten Wert des Pairs gibt es die Funktion fst (first), für den zweiten Wert gibt es die Funktion snd (second). Für das Pair und die dazugehörigen getter muss nichts neues implementiert werden, sondern es können dafür bereits bestehende Funktionen (Grundbausteine) verwendet werden. Das Pair ist gerade der Vireo. Die fst-Funktion ist gerade die Konstante Funktion. Die snd-Funktion ist gerade der Kite.

Implementation :

const pair    =    V;    // immutable datastructure pair

const fst     =    K;    // get first element from pair
const snd     =   KI;    // get second element from pair

Beispiele:

const pairOfNumbers = pair(1)(2);
const pairOfStrings = pair("Hello")("World");
    
pairOfNumbers(fst);        // 1
pairOfNumbers(snd);        // 2
    
pairOfStrings(fst);        // "Hello"
pairOfStrings(snd);        // "World"

MapPair

Die Funktion mapPair nimmt eine map-Funktion und ein Pair entgegen. Die Funktion gibt ein neues Pair mit den gemappten Werten zurück.

Implementation:

const mapPair = f => p => pair(f(p(fst)))(f(p(snd)));

Beispiele:

const mapFunction = x => x * 2;
const pairOfNNumbers = pair(5)(6);

const mappedPair = mapPair(mapFunction)(pairOfNNumbers); // pair(10)(12)

ShowPair

Die Funktion nimmt ein Pair entgegen und gibt die String Repräsentation des Pairs zurück.

Implementation:

const showPair = p => `${p(fst)} | ${p(snd)}`;

Beispiele:

const pairOfNNumbers = pair(5)(6);

const stringOfPair = showPair(pairOfNNumbers); // '5 | 6'

Triple

Das Triple ist eine unveränderliche Datenstruktur bestehend aus drei Elementen. Mit sogenannten "getter"-Funktionen kann auf diese Werte zugegriffen werden. Für alle Werte des Triple gibt es eine "getter"-Funktion. Ein Triple ist fast wie ein Pair, nur hat es einen Wert mehr.

Implementation:

const triple = x => y => z => f => f(x)(y)(z);

Beispiele:

// getter functions of triple
const firstOfTriple  = x => y => z => x;
const secondOfTriple = x => y => z => y;
const thirdOfTriple  = x => y => z => z;

// triple with 3 numbers
const tripleOfNumbers = triple(1)(2)(3);

tripleOfNumbers( firstOfTriple  );    // 1
tripleOfNumbers( secondOfTriple );    // 2
tripleOfNumbers( thirdOfTriple  );    // 3

Blackbird

Der Blackbird ist eine Funktion, die zwei Funktionen und zwei Argumente entgegennimmt. Die zweite Funktion wird auf die zwei übergebenen Argumente angewendet, das Ergebnis wird auf auf die erste Funktion angewendet. Der Blackbird hat ähnlichkeiten mit dem Bluebird.

Implementation:

const Blackbird = f => g => x => y => f(g(x)(y));

Beispiele:

const add = x => y => x + y;
const multiplyWithTwo = x => x * 2;

Blackbird(multiplyWithTwo)(add)(2)(3);      // 10
Blackbird(multiplyWithTwo)(add)(10)(20);    // 60

Last updated