Fachkonzept - Funktion höherer Ordnung
Grundidee und Präzisierung
Im letzten Abschnitt wurde u.a. der map-Operator eingeführt. Die vordefinierte Funktion List.map
verarbeitet eine übergebene Funktion, die auf alle Elemente einer übergebenen Liste angewandt wird.
> f x = -x
<function> : number -> number
> List.map f [3,0,-6,4]
[-3,0,6,-4] : List number
Die Funktion List.map
ist demach eine Funktion, die andere Funktionen als Datenwerte verarbeitet.
Eine solche Funktion wird auch Funktion höherer Ordnung genannt.
Eine Funktion höherer Ordnung ist eine Funktion, bei der unter den Übergabe- und Rückgabedaten mindestens eine Funktion als Datenwert vorkommt.
Partielle Funktionsaufrufe
Im Kontext von Funktionen höherer Ordnung sind partielle Funktionsaufrufe
oft hilfreich. Dabei wird eine Funktion nur mit einem Teil ihrer Parameter aufgerufen.
Es entsteht eine neue Funktion, die nur noch die übrigen Parameter erhält.
Prinzipiell ist das für eine beliebige Zahl an ausgelassenen Parametern möglich
(siehe Kapitel Currying)
In der Praxis besonders häufig ist der Fall, dass man den letzten Parameter weglässt und
eine Funktion entsteht, die dann genau einen Parameter benötigt.
Insbesondere für Funktionen wie List.map
oder List.filter
ist das oft praktisch.
Wir gehen im Beispiel von einer Funktion aus, die in einer Zeichenkette ab einer bestimmten Position die anderen Zeichen "ausixt":
ausixen : Char -> Int -> String -> String
ausixen x ab wort =
String.left ab wort ++
String.repeat (String.length wort - ab) (String.fromChar x)
> ausixen '_' 3 "Dieser Inhalt ist streng geheim!"
"Die_____________________________" : String
Wenn man die ersten beiden Parameter angibt und den letzten weglässt, erhält man eine
Funktion, bei der feststeht mit welchem Zeichen ab welcher Position "ausgeixt" wird.
Der Funktion muss nur noch eine Zeichenkette übergeben werden.
Auf diese Art partiell aufgerufen kann man sie auf List.map
anwenden:
> liste = ["Geheimtext", "Streng geheim", "Interne Daten"]
["Geheimtext","Streng geheim","Interne Daten"]
: List String
> List.map (ausixen '_' 3) liste
["Geh_______","Str__________","Int__________"]
: List String
> List.map (ausixen 'X' 5) liste
["GeheiXXXXX","StrenXXXXXXXX","InterXXXXXXXX"]
: List String
Definition einer Funktion höherer Ordnung
Im Alltag kommt man mit vordefinierten Funktionen höherer Ordnung recht weit, man kann aber auch selbst Funktionen höherer Ordnung schreiben. Als Beispiel betrachten wir eine Funktion, die eine andere Funktion entgegennimmt und zwei mal auf einen weiteren Parameter anwendet.
applyTwice : (a -> a) -> a -> a
applyTwice fun x =
fun (fun x)
> f x = x * 2
<function> : number -> number
> applyTwice f 2
8 : number
> g x = x ++ x
<function> : appendable -> appendable
> applyTwice g "Hallo"
"HalloHalloHalloHallo" : String