Einführung in die funktionale Programmierung

85
Funktioniert’s? Funktionale Programmierung für Anfänger

Transcript of Einführung in die funktionale Programmierung

Page 1: Einführung in die funktionale Programmierung

Funktioniert’s?

Funktionale Programmierung für Anfänger

Page 2: Einführung in die funktionale Programmierung

Funktional, das ist doch nur für Esoteriker?!

I ABN AMRO Amsterdam Risikoanalysen InvestmentbankingI AT&T Netzwerksicherheit: Verarbeitung von

Internet-MissbrauchsmeldungenI Bank of America Merril Lynch

Backend: Laden & Transformieren von DatenI Barclays Capital Quantitative Analytics Group

Mathematische Modellierung von DerivatenI Bluespec, Inc. Modellierung & Verifikation integrierter SchaltkreiseI Credit Suisse Prüfen und Bearbeiten von SpreadsheetsI Deutsche Bank Equity Proprietary Trading, Directional Credit

Trading Gesamte Software-InfrastrukturI Facebook Interne ToolsI Factis Research, Freiburg Mobil-Lösungen (Backend)I fortytools gmbh Webbasierte Produktivitätstools - REST-BackendI Functor AB, Stockholm Statische Codeanalyse

Page 3: Einführung in die funktionale Programmierung

Funktional, das ist doch nur für Esoteriker?!I ABN AMRO Amsterdam Risikoanalysen InvestmentbankingI AT&T Netzwerksicherheit: Verarbeitung von

Internet-MissbrauchsmeldungenI Bank of America Merril Lynch

Backend: Laden & Transformieren von DatenI Barclays Capital Quantitative Analytics Group

Mathematische Modellierung von DerivatenI Bluespec, Inc. Modellierung & Verifikation integrierter SchaltkreiseI Credit Suisse Prüfen und Bearbeiten von SpreadsheetsI Deutsche Bank Equity Proprietary Trading, Directional Credit

Trading Gesamte Software-InfrastrukturI Facebook Interne ToolsI Factis Research, Freiburg Mobil-Lösungen (Backend)I fortytools gmbh Webbasierte Produktivitätstools - REST-BackendI Functor AB, Stockholm Statische Codeanalyse

Page 4: Einführung in die funktionale Programmierung

Funktional, das ist doch nur für Esoteriker?!I Galois, Inc Security, Informationssicherheit, KryptographieI Google Interne ProjekteI IMVU, Inc. Social entertainmentI JanRain Netzwerk- und Web-SoftwareI MITRE Analyse kryptographischer ProtokolleI New York Times Bildverarbeitung für die New York Fashion WeekI NVIDIA In-House ToolsI Parallel Scientific Hochskalierbares Cluster-VerwaltungssystemI Sankel Software CAD/CAM, Spiele, ComputeranimationI Silk, Amsterdam Filtern und Visualisieren großer DatenmengenI Skedge Me Online-TerminvereinbarungenI Standard Chartered BankensoftwareI Starling Software, Tokio Automatisiertes OptionshandelssystemI Suite Solutions Verwaltung technischer Dokumentationen

(Quelle: http://www.haskell.org/haskellwiki/Haskell_in_industry)

Page 5: Einführung in die funktionale Programmierung

Bekannte funktionale Sprachen

Lisp

Scheme

ML

OCamlMiranda

F#

ErlangClojure

Scala

Haskell

(JavaScript)

(Java 8)Haskell

(JavaScript)

(Java 8)

Page 6: Einführung in die funktionale Programmierung

Bekannte funktionale Sprachen

Lisp

Scheme

ML

OCamlMiranda

F#

ErlangClojure

Scala

Haskell

(JavaScript)

(Java 8)

Haskell

(JavaScript)

(Java 8)

Page 7: Einführung in die funktionale Programmierung

Bekannte funktionale Sprachen

Lisp

Scheme

ML

OCamlMiranda

F#

ErlangClojure

Scala

Haskell

(JavaScript)

(Java 8)

Haskell

(JavaScript)

(Java 8)

Page 8: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Immutability

I Jeder Variablen darf nur einmal ein Wert zugewiesen werdenI In Java nicht direkt unterstütztI Kann trotzdem leicht verwirklicht werden:

class Point {

private final int x, y;

public Point (int x, int y) {

this.x = x;

this.y = y;

}

// only read x and y in the remaining code

}

Page 9: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Immutability

I Jeder Variablen darf nur einmal ein Wert zugewiesen werdenI In Java nicht direkt unterstütztI Kann trotzdem leicht verwirklicht werden:

class Point {

private final int x, y;

public Point (int x, int y) {

this.x = x;

this.y = y;

}

// only read x and y in the remaining code

}

Page 10: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Immutability

I Jeder Variablen darf nur einmal ein Wert zugewiesen werden

I In Java nicht direkt unterstütztI Kann trotzdem leicht verwirklicht werden:

class Point {

private final int x, y;

public Point (int x, int y) {

this.x = x;

this.y = y;

}

// only read x and y in the remaining code

}

Page 11: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Immutability

I Jeder Variablen darf nur einmal ein Wert zugewiesen werdenI In Java nicht direkt unterstützt

I Kann trotzdem leicht verwirklicht werden:

class Point {

private final int x, y;

public Point (int x, int y) {

this.x = x;

this.y = y;

}

// only read x and y in the remaining code

}

Page 12: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Immutability

I Jeder Variablen darf nur einmal ein Wert zugewiesen werdenI In Java nicht direkt unterstütztI Kann trotzdem leicht verwirklicht werden:

class Point {

private final int x, y;

public Point (int x, int y) {

this.x = x;

this.y = y;

}

// only read x and y in the remaining code

}

Page 13: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheit

I „alles, was den Ablauf eines Computerprogramms oder die Außenweltverändert, ohne von einer Funktion berechnet worden zu sein“

I Ein-/AusgabeI ExceptionsI LoggingI Abhängigkeit von (externen) KonfigurationenI Veränderungen des ZustandsI Nichtdeterminismus (z. B. Zufallszahlengenerator)

I Manche Sprachen zeigen das Vorhandensein von Seiteneffekten sogarin der Typsignatur an

Page 14: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheit

I „alles, was den Ablauf eines Computerprogramms oder die Außenweltverändert, ohne von einer Funktion berechnet worden zu sein“

I Ein-/AusgabeI ExceptionsI LoggingI Abhängigkeit von (externen) KonfigurationenI Veränderungen des ZustandsI Nichtdeterminismus (z. B. Zufallszahlengenerator)

I Manche Sprachen zeigen das Vorhandensein von Seiteneffekten sogarin der Typsignatur an

Page 15: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheit

I „alles, was den Ablauf eines Computerprogramms oder die Außenweltverändert, ohne von einer Funktion berechnet worden zu sein“

I Ein-/AusgabeI ExceptionsI LoggingI Abhängigkeit von (externen) KonfigurationenI Veränderungen des ZustandsI Nichtdeterminismus (z. B. Zufallszahlengenerator)

I Manche Sprachen zeigen das Vorhandensein von Seiteneffekten sogarin der Typsignatur an

Page 16: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheit

I „alles, was den Ablauf eines Computerprogramms oder die Außenweltverändert, ohne von einer Funktion berechnet worden zu sein“

I Ein-/AusgabeI ExceptionsI LoggingI Abhängigkeit von (externen) KonfigurationenI Veränderungen des ZustandsI Nichtdeterminismus (z. B. Zufallszahlengenerator)

I Manche Sprachen zeigen das Vorhandensein von Seiteneffekten sogarin der Typsignatur an

Page 17: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheitauch nicht direkt durch Java 8 unterstützt - Codierungsregeln helfen

class SeparationOfSideEffects {

public void withSideEffect(){

String initialValue = System.console().readLine();

String result = withoutSideEffect(initialValue);

System.out.println("The Result: " + result);

}

public static String withoutSideEffect(String initialValue){

return /* function result */ ;

}

}

Page 18: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Seiteneffektfreiheitauch nicht direkt durch Java 8 unterstützt - Codierungsregeln helfen

class SeparationOfSideEffects {

public void withSideEffect(){

String initialValue = System.console().readLine();

String result = withoutSideEffect(initialValue);

System.out.println("The Result: " + result);

}

public static String withoutSideEffect(String initialValue){

return /* function result */ ;

}

}

Page 19: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Funktionen sind „first order citizens“

Mit Funktionen kann man dasselbe machen wie mit Strings oder Zahlen

Page 20: Einführung in die funktionale Programmierung

Was ist denn an funktionaler Programmierung so besonders?

Funktionen sind „first order citizens“Mit Funktionen kann man dasselbe machen wie mit Strings oder Zahlen

Page 21: Einführung in die funktionale Programmierung

Funktionen sind Werte

Java 8: Lambdas (mit eigenem Funktionsinterface)

interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:

times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 22: Einführung in die funktionale Programmierung

Funktionen sind WerteJava 8: Statische Methodenclass Examples { static int staticTimes (int x, int y) { return x * y; } }

IntBinaryOperator timesVar = Examples::staticTimes;

timesVar.applyAsInt(3, 5); // 15

Java 8: Lambdas (mit eigenem Funktionsinterface)interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 23: Einführung in die funktionale Programmierung

Funktionen sind WerteJava 8: Objektmethodenclass Examples { int times (int x, int y) { return x * y; } }

Examples examples = new Examples();

IntBinaryOperator timesVar = examples::times;

timesVar.applyAsInt(3, 5); // 15

Java 8: Lambdas (mit eigenem Funktionsinterface)interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 24: Einführung in die funktionale Programmierung

Funktionen sind WerteJava 8: Lambdas

IntBinaryOperator times = (x, y) -> x * y;

times.applyAsInt(3, 5); // 15

Java 8: Lambdas (mit eigenem Funktionsinterface)

interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:

times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 25: Einführung in die funktionale Programmierung

Funktionen sind Werte

Java 8: Lambdas (mit eigenem Funktionsinterface)

interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:

times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 26: Einführung in die funktionale Programmierung

Funktionen sind Werte

Java 8: Lambdas (mit eigenem Funktionsinterface)

interface TimesFunction { int eval(int x, int y); }

TimesFunction times = (x, y) -> x * y;

times.eval(3, 5); // 15

Haskell:

times x y = x * y

timesVar = times

timesVar 3 5 -- 15

Page 27: Einführung in die funktionale Programmierung

Funktionen sind Funktionsparameter

Java 8:

class Examples {

static int apply(IntUnaryOperator func, int arg) {

return func.applyAsInt(arg);

}

}

Examples.apply(x -> 3 * x, 5); // 15

Haskell:

apply func arg = func arg

apply (\ x -> 3 * x) 5 -- 15

Page 28: Einführung in die funktionale Programmierung

Funktionen sind Funktionsparameter

Java 8:

class Examples {

static int apply(IntUnaryOperator func, int arg) {

return func.applyAsInt(arg);

}

}

Examples.apply(x -> 3 * x, 5); // 15

Haskell:

apply func arg = func arg

apply (\ x -> 3 * x) 5 -- 15

Page 29: Einführung in die funktionale Programmierung

Funktionen sind Funktionsparameter

Java 8:

class Examples {

static int apply(IntUnaryOperator func, int arg) {

return func.applyAsInt(arg);

}

}

Examples.apply(x -> 3 * x, 5); // 15

Haskell:

apply func arg = func arg

apply (\ x -> 3 * x) 5 -- 15

Page 30: Einführung in die funktionale Programmierung

Funktionen sind Rückgabewerte

Java 8:

interface FunctionFunction { IntUnaryOperator eval(int x); }

FunctionFunction times = x -> { return y -> x * y; };

times.eval(3).applyAsInt(5); // 15

Haskell:

times x = (\y -> x * y)

times 3 5 -- 15

Page 31: Einführung in die funktionale Programmierung

Funktionen sind Rückgabewerte

Java 8:

interface FunctionFunction { IntUnaryOperator eval(int x); }

FunctionFunction times = x -> { return y -> x * y; };

times.eval(3).applyAsInt(5); // 15

Haskell:

times x = (\y -> x * y)

times 3 5 -- 15

Page 32: Einführung in die funktionale Programmierung

Funktionen sind Rückgabewerte

Java 8:

interface FunctionFunction { IntUnaryOperator eval(int x); }

FunctionFunction times = x -> { return y -> x * y; };

times.eval(3).applyAsInt(5); // 15

Haskell:

times x = (\y -> x * y)

times 3 5 -- 15

Page 33: Einführung in die funktionale Programmierung

Komisch, oder?

Java 8: Zwei verschiedene Aufrufe

IntBinaryOperator times = (x, y) -> x * y;

times.applyAsInt(3, 5); // 15

FunctionFunction times = x -> { return y -> x * y; };

times.eval(3).applyAsInt(5); // 15

Haskell: Zweimal derselbe Aufruf

times x y = x * y

times 3 5 -- 15

times x = (\y -> x * y)

times 3 5 -- 15

Page 34: Einführung in die funktionale Programmierung

Currying! (oder auch Schönfinkeln)

In manchen funktionalen Sprachen schreiben wir:

times x y = x * y

und eigentlich passiert Folgendes:

times x = (\y -> x * y)

Denn: Funktionen haben immer genau ein Argument

Nutzen: Partielle Evaluierung:

times x y = x * y

times3 = times 3

times3 5 -- 15

Page 35: Einführung in die funktionale Programmierung

Currying! (oder auch Schönfinkeln)

In manchen funktionalen Sprachen schreiben wir:

times x y = x * y

und eigentlich passiert Folgendes:

times x = (\y -> x * y)

Denn: Funktionen haben immer genau ein Argument

Nutzen: Partielle Evaluierung:

times x y = x * y

times3 = times 3

times3 5 -- 15

Page 36: Einführung in die funktionale Programmierung

Currying! (oder auch Schönfinkeln)

In manchen funktionalen Sprachen schreiben wir:

times x y = x * y

und eigentlich passiert Folgendes:

times x = (\y -> x * y)

Denn: Funktionen haben immer genau ein Argument

Nutzen: Partielle Evaluierung:

times x y = x * y

times3 = times 3

times3 5 -- 15

Page 37: Einführung in die funktionale Programmierung

Currying! (oder auch Schönfinkeln)

In manchen funktionalen Sprachen schreiben wir:

times x y = x * y

und eigentlich passiert Folgendes:

times x = (\y -> x * y)

Denn: Funktionen haben immer genau ein Argument

Nutzen: Partielle Evaluierung:

times x y = x * y

times3 = times 3

times3 5 -- 15

Page 38: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: filter

I filter oder auch select

I Nimmt eine Collection und eine FunktionI Liefert diejenigen Elemente der Collection, für die die Funktion true

ergibt

Java 8:

Stream<Integer> filteredStream =

asList(1, 2, 3, 4).stream().filter(x -> x % 2 == 0);

filteredStream.toArray(); // new Integer[]{2, 4}

filteredStream.collect(Collectors.toList()); // Liste mit 2 und 4

Haskell:

filter (\x -> x `mod` 2 == 0) [1,2,3,4] -- [2,4]

Page 39: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: filter

I filter oder auch selectI Nimmt eine Collection und eine FunktionI Liefert diejenigen Elemente der Collection, für die die Funktion true

ergibt

Java 8:

Stream<Integer> filteredStream =

asList(1, 2, 3, 4).stream().filter(x -> x % 2 == 0);

filteredStream.toArray(); // new Integer[]{2, 4}

filteredStream.collect(Collectors.toList()); // Liste mit 2 und 4

Haskell:

filter (\x -> x `mod` 2 == 0) [1,2,3,4] -- [2,4]

Page 40: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: filter

I filter oder auch selectI Nimmt eine Collection und eine FunktionI Liefert diejenigen Elemente der Collection, für die die Funktion true

ergibt

Java 8:

Stream<Integer> filteredStream =

asList(1, 2, 3, 4).stream().filter(x -> x % 2 == 0);

filteredStream.toArray(); // new Integer[]{2, 4}

filteredStream.collect(Collectors.toList()); // Liste mit 2 und 4

Haskell:

filter (\x -> x `mod` 2 == 0) [1,2,3,4] -- [2,4]

Page 41: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: filter

I filter oder auch selectI Nimmt eine Collection und eine FunktionI Liefert diejenigen Elemente der Collection, für die die Funktion true

ergibt

Java 8:

Stream<Integer> filteredStream =

asList(1, 2, 3, 4).stream().filter(x -> x % 2 == 0);

filteredStream.toArray(); // new Integer[]{2, 4}

filteredStream.collect(Collectors.toList()); // Liste mit 2 und 4

Haskell:

filter (\x -> x `mod` 2 == 0) [1,2,3,4] -- [2,4]

Page 42: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: map

I map oder auch collect

I Nimmt eine Collection und eine FunktionI Liefert eine Collection, in der die Funktion auf jedes Element der

ursprünglichen Collection angewandt wurde

Java 8:

Arrays.asList(1, 2, 3, 4).stream().map(x -> x + 5).toArray();

// new Integer[]{6, 7, 8, 9}

Haskell:

map (\x -> x + 5) [1,2,3,4] -- [6,7,8,9]

Page 43: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: map

I map oder auch collectI Nimmt eine Collection und eine FunktionI Liefert eine Collection, in der die Funktion auf jedes Element der

ursprünglichen Collection angewandt wurde

Java 8:

Arrays.asList(1, 2, 3, 4).stream().map(x -> x + 5).toArray();

// new Integer[]{6, 7, 8, 9}

Haskell:

map (\x -> x + 5) [1,2,3,4] -- [6,7,8,9]

Page 44: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: map

I map oder auch collectI Nimmt eine Collection und eine FunktionI Liefert eine Collection, in der die Funktion auf jedes Element der

ursprünglichen Collection angewandt wurde

Java 8:

Arrays.asList(1, 2, 3, 4).stream().map(x -> x + 5).toArray();

// new Integer[]{6, 7, 8, 9}

Haskell:

map (\x -> x + 5) [1,2,3,4] -- [6,7,8,9]

Page 45: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: map

I map oder auch collectI Nimmt eine Collection und eine FunktionI Liefert eine Collection, in der die Funktion auf jedes Element der

ursprünglichen Collection angewandt wurde

Java 8:

Arrays.asList(1, 2, 3, 4).stream().map(x -> x + 5).toArray();

// new Integer[]{6, 7, 8, 9}

Haskell:

map (\x -> x + 5) [1,2,3,4] -- [6,7,8,9]

Page 46: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: reduceI reduce oder auch foldl / foldr oder inject

Java 8:

Arrays.asList(2, 3, 4, 5).stream().reduce(1, (x, y) -> x*y); // 120

Haskell:

foldl (*) 1 [2,3,4,5] -- 120

Page 47: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: reduceI reduce oder auch foldl / foldr oder injectI Nimmt eine Collection, eine Funktion und einen StartwertI Verbindet Startwert und erstes Element der Collection mit Hilfe der

FunktionI Verbindet das Ergebnis mit dem nächsten Element der CollectionI Setzt dies für alle Elemente der Collection fort, bis nur noch ein

Element übrigbleibt

Java 8:Arrays.asList(2, 3, 4, 5).stream().reduce(1, (x, y) -> x*y); // 120

Haskell:foldl (*) 1 [2,3,4,5] -- 120

Page 48: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: reduceI reduce oder auch foldl / foldr oder inject

Java 8:

Arrays.asList(2, 3, 4, 5).stream().reduce(1, (x, y) -> x*y); // 120

Haskell:

foldl (*) 1 [2,3,4,5] -- 120

Page 49: Einführung in die funktionale Programmierung

Wichtige Bibliotheksfunktionen: reduceI reduce oder auch foldl / foldr oder inject

Java 8:

Arrays.asList(2, 3, 4, 5).stream().reduce(1, (x, y) -> x*y); // 120

Haskell:

foldl (*) 1 [2,3,4,5] -- 120

Page 50: Einführung in die funktionale Programmierung

Typinferenz

I Haskell: starkes statisches TypsystemI Leichtgewichtige Verwendung dank TypinferenzI Herleitung des allgemeinst möglichen Typs

Beispiel:

f x = x

Typ:

f :: a -> a

a : Typvariable (vergleichbar mit Generics in Java o. ä.)-> Funktionstyp (Argumenttyp steht links, Ergebnistyp steht rechts)

Page 51: Einführung in die funktionale Programmierung

Typinferenz

I Haskell: starkes statisches TypsystemI Leichtgewichtige Verwendung dank TypinferenzI Herleitung des allgemeinst möglichen Typs

Beispiel:

f x = x

Typ:

f :: a -> a

a : Typvariable (vergleichbar mit Generics in Java o. ä.)-> Funktionstyp (Argumenttyp steht links, Ergebnistyp steht rechts)

Page 52: Einführung in die funktionale Programmierung

Typinferenz

I Haskell: starkes statisches TypsystemI Leichtgewichtige Verwendung dank TypinferenzI Herleitung des allgemeinst möglichen Typs

Beispiel:

f x = x

Typ:

f :: a -> a

a : Typvariable (vergleichbar mit Generics in Java o. ä.)-> Funktionstyp (Argumenttyp steht links, Ergebnistyp steht rechts)

Page 53: Einführung in die funktionale Programmierung

Typinferenz (2)

f x = x + 1

Typ:

f :: Num a => a -> a

Num a : Typklasse. Einschränkung der Typvariablen a auf numerischeTypen

Empfehlung: Typsignatur stets annotieren! Zur Überprüfung der eigenenAnnahmen.

Page 54: Einführung in die funktionale Programmierung

Typinferenz (2)

f x = x + 1

Typ:

f :: Num a => a -> a

Num a : Typklasse. Einschränkung der Typvariablen a auf numerischeTypen

Empfehlung: Typsignatur stets annotieren! Zur Überprüfung der eigenenAnnahmen.

Page 55: Einführung in die funktionale Programmierung

Typinferenz (2)

f x = x + 1

Typ:

f :: Num a => a -> a

Num a : Typklasse. Einschränkung der Typvariablen a auf numerischeTypen

Empfehlung: Typsignatur stets annotieren! Zur Überprüfung der eigenenAnnahmen.

Page 56: Einführung in die funktionale Programmierung

Eine einfache Berechnung

sum =10∑i=1

i2

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

Page 57: Einführung in die funktionale Programmierung

Eine einfache Berechnung

sum =10∑i=1

i2

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

Page 58: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 59: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 60: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10

I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 61: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer Zahl

I Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 62: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der Folge

I Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 63: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier Zahlen

I Aufsummieren der Quadratzahlen

Page 64: Einführung in die funktionale Programmierung

Exkurs: Clean Code

Single Responsibility Principle

Wie viele Verantwortlichkeiten hat dieser Code?

int sum = 0;

for(int i = 1; i <= 10; i++) {

sum = sum + i * i;

}

I Erzeugen der Zahlenfolge von 1 bis 10I Quadrieren einer ZahlI Berechnen der Quadratzahl jeder Zahl in der FolgeI Addieren zweier ZahlenI Aufsummieren der Quadratzahlen

Page 65: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 66: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 67: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 68: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 69: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 70: Einführung in die funktionale Programmierung

Trennen der VerantwortlichkeitenI Erzeugen der Zahlenfolge von 1 bis 10

IntStream sequence = IntStream.rangeClosed(1, 10);

I Quadrieren einer Zahl

IntUnaryOperator square = x -> x*x;

I Berechnen der Quadratzahl jeder Zahl in der Folge

IntStream squaredSequence = sequence.map(square);

I Addieren zweier Zahlen

IntBinaryOperator add = (x,y) -> x+y;

I Aufsummieren der Quadratzahlen

Integer sum = squaredSequence.reduce(0, add);

Page 71: Einführung in die funktionale Programmierung

Zusammensetzen der Komponenten

Java 8:

IntStream.rangeClosed(1, 10).map(x -> x*x).reduce(0, (x,y) -> x+y); // 385

Haskell:

foldl (+) 0 (map (\x -> x*x) [1..10]) -- 385

oder

(>.>) x f = f x

[1..10] >.> map (\x -> x*x) >.> foldl (+) 0 -- 385

Page 72: Einführung in die funktionale Programmierung

Zusammensetzen der Komponenten

Java 8:

IntStream.rangeClosed(1, 10).map(x -> x*x).reduce(0, (x,y) -> x+y); // 385

Haskell:

foldl (+) 0 (map (\x -> x*x) [1..10]) -- 385

oder

(>.>) x f = f x

[1..10] >.> map (\x -> x*x) >.> foldl (+) 0 -- 385

Page 73: Einführung in die funktionale Programmierung

Zusammensetzen der Komponenten

Java 8:

IntStream.rangeClosed(1, 10).map(x -> x*x).reduce(0, (x,y) -> x+y); // 385

Haskell:

foldl (+) 0 (map (\x -> x*x) [1..10]) -- 385

oder

(>.>) x f = f x

[1..10] >.> map (\x -> x*x) >.> foldl (+) 0 -- 385

Page 74: Einführung in die funktionale Programmierung

Uff!

OK, alle einmal tief durchatmen :-)

Page 75: Einführung in die funktionale Programmierung

Pattern Matching

Fibonacci-Funktion „naiv“:

fib x = if x < 2 then x else fib (x-1) + fib (x-2)

Fibonacci-Funktion mit Pattern Matching:

fib 0 = 0

fib 1 = 1

fib x = fib (x-1) + fib (x-2)

Page 76: Einführung in die funktionale Programmierung

Pattern Matching

Fibonacci-Funktion „naiv“:

fib x = if x < 2 then x else fib (x-1) + fib (x-2)

Fibonacci-Funktion mit Pattern Matching:

fib 0 = 0

fib 1 = 1

fib x = fib (x-1) + fib (x-2)

Page 77: Einführung in die funktionale Programmierung

Algebraische Datentypen

Binärbaum:

data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:

treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 78: Einführung in die funktionale Programmierung

Algebraische DatentypenBinärbaum:data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 79: Einführung in die funktionale Programmierung

Algebraische Datentypen

Binärbaum:

data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:

treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 80: Einführung in die funktionale Programmierung

Algebraische Datentypen

Binärbaum:

data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:

treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 81: Einführung in die funktionale Programmierung

Algebraische Datentypen

Binärbaum:

data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:

treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 82: Einführung in die funktionale Programmierung

Algebraische Datentypen

Binärbaum:

data Tree =

Node Tree Tree

| Leaf Int

myTree = Node (Node (Leaf 4) (Node (Leaf 7) (Leaf 1))) (Leaf 3)

Summenfunktion:

treeSum (Leaf x) = x

treeSum (Node m n) = treeSum m + treeSum n

treeSum myTree -- 15

Page 83: Einführung in die funktionale Programmierung

Fazit

I Funktionale Programmierung ist verbreiteter als man denktI Manches lässt sich in den nicht-funktionalen Alltag integrierenI Viele Sprachen bringen funktionale Aspekte oder Zusatzmodule mit

Referenz:

I Haskell: http://www.haskell.org

Page 84: Einführung in die funktionale Programmierung

Fazit

I Funktionale Programmierung ist verbreiteter als man denktI Manches lässt sich in den nicht-funktionalen Alltag integrierenI Viele Sprachen bringen funktionale Aspekte oder Zusatzmodule mit

Referenz:

I Haskell: http://www.haskell.org

Page 85: Einführung in die funktionale Programmierung

Vielen Dank!Code & Folien auf GitHub:

https://github.com

/NicoleRauch/FunctionalProgrammingForBeginners

Nicole Rauch

E-Mail [email protected] @NicoleRauch

Web http://www.nicole-rauch.de

I Artikel in der nächsten (?) Java AktuellI Ganztägiger Workshop