Methoden höherer Ordnung
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
1
Das Grundprinzip
Funktionen werden in der funktionalen
Programmierung wie alle anderen Daten
behandelt.
Daher können Funktionen
sowohl Argumente,
als auch Ergebnisse
von Funktionen sein.
In Haskell:
accu f (x:[]) = x
accu f (x:xs) = f x (accu f xs)
accu angewandt auf f und eine Liste
mit nur dem Element x
accu angewandt auf f und eine Liste
mit dem Kopf x und dem Rest xs
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
2
Wie ist das in Java?
In Java werden Methoden anders als andere Daten
behandelt.
Wir lernen eine Möglichkeit kennen, um Methoden zu
definieren, die indirekt
andere Methoden als Argumente verarbeiten
können oder
andere Methoden als Ergebnis liefern können.
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
3
Erst einmal was Anderes
Dog[] dogs ={
new Dog("Snoopy", 42, Unit.CM),
new Dog("Bello", 23, Unit.CM),
new Dog("Lassie", 23, Unit.CM)
};
Arrays.sort(dogs);
Was passiert?
ClassCastException nach Comparable
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
4
Vergleichbare Hunde
class Dog implements Comparable<Dog>{
...
public int compareTo(Dog other) {
if(size<other.size) return -1;
else if(size>other.size) return 1;
else return name.compareTo(other.name);
}
}
Jetzt klappt es!
Nach welchen Kriterien wird sortiert?
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
5
Eine flexiblere Lösung
sort(T[] a, Comparator<? super T> c)
public interface Comparator<Dog>{
int compare(Dog dog1, Dog dog2);
}
Wie funktioniert das?
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
6
Eine flexiblere Lösung
class DogComparator implements Comparator<Dog>{
public int compare(Dog dog1, Dog dog2){
if(dog1.equals(dog2)){
return 0;
}
int result = dog1.getName().compareTo(dog2.getName());
if(result!=0){
return result;
}
return dog1.getSize()<dog2.getSize() ? -1 : 1;
}
}
Arrays.sort(dogs, new DogComparator());
Nach welchen Kriterien wird hier sortiert?
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
7
Alles auf Einmal
Arrays.sort(dogs,
new Comparator<Dog>(){
public int compare(Dog dog1, Dog dog2) {
if(dog1.equals(dog2)){return 0;}
final int result
= dog1.getName().compareTo(dog2.getName());
if(result!=0){return result;}
return dog1.getSize()<dogs.getSize() ? -1 : 1;
}
}
);
Anonyme innere Klasse, die Comparator<Dog>
implementiert.
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
8
Entwurfsmuster
Objektorientierte Programmierung erfordert
einige Erfahrung
Viele Probleme treten immer wieder auf
Typische Problemstellungen werden zusammen
mit einer Standardlösung zu einem
Entwurfsmuster zusammengefasst.
Es gibt einen anerkannten Katalog von Mustern.
Der Katalog bietet nicht nur Lösungen für
Standardprobleme an, sondern bietet auch eine
Terminologie, die erfahrene Programmierer
kennen.
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
9
Das Strategiemuster
„Definiere eine Familie von Algorithmen, kapsele jeden
einzelnen und mache sie austauschbar.
Das Strategiemuster ermöglicht es, den Algorithmus
unabhängig
̈
von ihn nutzenden Klienten zu variieren.“
Hier:
Algorithmus = compareTo-Methode
Kapsel = Comparator
Klient = sort
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
10
Strategiemuster - Noch ein Beispiel
Thread t = new Thread(
new Runnable(){
public void run() {
while(true)
System.out.println(new Date());
}
}
);
t.start();
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
11
Das Strategiemuster und Funktionale
Auch wenn Java keine Methoden höherer
Ordnung bietet:
Mit Hilfe des Strategiemuster können wir
Methoden höherer Ordnung nachbilden.
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
12
Einfache Codes
Der Cäsar-Code
HELLO
IFMMP
Jeder Buchstabe wir durch seinen alphabetischen
Nachfolger ersetzt.
Erweiterung:
Nicht den unmittelbaren Nachfolger wählen, sondern
den jeweils k-ten Nachfolger
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
13
Funktionen als Objekte erster Klasse
interface Function<T> {
T f(T v);
}
class Coder implements Function<Character>{
private int offset;
public Coder(int offset){this.offset = offset%26;}
public Character f(Character letter) {
if(letter>'Z' || letter<'A'){
throw new IllegalArgumentException(letter.toString());
}
return (char)('A'+(letter-'A'+offset)%26);
}
}
Cäsar entspricht Coder(1)
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
14
Eine Methode höherer Ordnung
String transformer(Function<Character> coder, String text){
final StringBuilder result
= new StringBuilder(text.length());
for(int i=0; i<text.length(); i++){
final Character coded = coder.f(text.charAt(i));
result.append(coded);
}
return result.toString();
}
Der zu verschlüsselnde Text entspricht dem zweiten
Parameter,
Die zeichenweise Abbildung entspricht dem ersten
Parameter
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
15
Beispiel zu Anwendung
transformer(new Coder(23), "HALLO")
Liefert EBIIL
transformer(new Coder(-23), "EBIIL")
Liefert HALLO
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
16
Methode mit einer Methode als Ergebnis
= Methode höherer Ordnung
Function<String> transformer(final Function<Character> coder){
return new Function<String>(){
public String f(String text) {
return transformer(coder, text);
}
};
}
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
17
Beispiel
Function<String> encoder = transformer(
new Coder(23)
);
Function<String> decoder = transformer(
new Coder(-23)
);
System.out.println(decoder.f(encoder.f("HELLO")));
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
18
Alles klar?
Eine Funktion höherer Ordnung
ist eine Funktion, der man Funktionen als Argument
übergeben
̈
kann oder deren Ergebnis eine Funktion
ist.
erlaubt es, Funktionen zu verallgemeinern, da Teile
ihrer Funktionalität parametrisiert werden können.
kann in jeder funktionalen Programmiersprache
benutzt werden.
gibt es in Java nicht. In Java kann man ersatzweise
mit dem Strategiemuster arbeiten.
L. Piepmeyer: Funktionale Programmierung - Funktionen höherer Ordnung
19