Funktionale Programmierung mit Haskell/ Pattern Matching bei Funktionen
Im Kapitel über Listen wird die Funktion zweites
so definiert:
Überblick
[Bearbeiten]-- Liefert das zweite Element einer Liste
zweites [] = []
zweites [a] = []
zweites (a:b:xs) = [b]
Bisher wurde diese Funktion unter dem Gesichtspunkt der Listenverarbeitung besprochen, aber sie wirft noch eine andere Frage auf: Gibt es wirklich "die" Funktion zweites
? Für Haskell existieren drei Funktionen des selben Namens, die sich durch den Übergabeparameter unterscheiden. Die erste der drei Funktionen wird angesprochen, wenn zweites
mit leerer Liste aufgerufen wird, die zweite Funktion gilt für den Aufruf mit einer einelementigen Liste, und die dritte Funktion gilt bei längeren Listen. Jede Zeile ist eine Definition für sich, die Reihenfolge der Definitionen ist egal.
Diese Eigenschaft von Funktionen heißt pattern matching, also Mustervergleich.
Beispiel für Pattern Matching
[Bearbeiten]Sie kann auch als Alternative von Key-Value-Paaren verwendet werden, wie im Beispiel mit den Ländervorwahlen:
landVorwahl "Afghanistan" = 93
landVorwahl "Aegypten" = 20
landVorwahl "Albanien" = 355
landVorwahl "Algerien" = 213
landVorwahl _ = 0
main = do
putStrLn "Bitte ein Land eingeben"
datString <- getLine
let eingabeLand = datString
if (landVorwahl eingabeLand > 0)
then putStrLn ("die Vorwahl von "++eingabeLand++" ist +"++ show (landVorwahl eingabeLand))
else putStrLn ("Das Land "++eingabeLand++" ist nicht hinterlegt")
Ok, modules loaded: Main.
*Main> main
Bitte ein Land eingeben
Albanien
die Vorwahl von Albanien ist +355
*Main> main
Bitte ein Land eingeben
Europa
Das Land Europa ist nicht hinterlegt
*Main>
In diesem Beispiel gibt es eine Funktion landVorwahl
, die für jedes Land mit einem neuen Wert belegt ist. In der letzten Zeile ist landVorwahl
mit dem Wildcard-Operator _
hinterlegt. Dies bewirkt, dass bei allen nicht definierten Übergabestrings die Null zurückgegeben wird.
Grenzen des Pattern Matching
[Bearbeiten]Pattern-Matching hat seine Grenzen, wenn der Typ des Übergabeparameters nicht eingehalten wird. Im folgenden Beispiel werden unter den gleichen Funktionsnamen die Eingabeparameter Listen und 2-und 3-Tupel vermischt; so etwas lässt der Kompiler nicht zu:
-- Eine fehlerhafte Definition:
zweites [] = []
zweites [a] = []
zweites (a:b:xs) = [b]
zweites (_,a) = a
zweites (_,a,_) = a
Ebenfalls nicht möglich sind Patterns, die Funktionen verwenden.
-- Eine fehlerhafte Definition:
letztes (_++[l]) = [l] -- hier scheitert es, weil (++) eine Funktion ist.
letztes _ = []