Haskell Language
Teilanwendung
Suche…
Bemerkungen
Lassen Sie uns einige Missverständnisse klären, die Anfänger machen könnten.
Möglicherweise haben Sie folgende Funktionen kennen gelernt:
max :: (Ord a) => a -> a -> a
max m n
| m >= n = m
| otherwise = n
Anfänger werden normalerweise max :: (Ord a) => a -> a -> a
als Funktion anzeigen, die zwei Argumente (Werte) vom Typ a
akzeptiert und einen Wert vom Typ a
zurückgibt. Was jedoch wirklich passiert, ist, dass max
ein Argument vom Typ a
übernimmt und eine Funktion vom Typ a -> a
. Diese Funktion nimmt dann ein Argument vom Typ a
und gibt einen Endwert vom Typ a
.
In der Tat kann max
als max :: (Ord a) => a -> (a -> a)
Beachten Sie die Typensignatur von max
:
Prelude> :t max
max :: Ord a => a -> a -> a
Prelude> :t (max 75)
(max 75) :: (Num a, Ord a) => a -> a
Prelude> :t (max "Fury Road")
(max "Fury Road") :: [Char] -> [Char]
Prelude> :t (max "Fury Road" "Furiosa")
(max "Fury Road" "Furiosa") :: [Char]
max 75
und max "Fury Road"
mag nicht wie Funktionen aussehen , aber in Wirklichkeit sind sie es.
Die Verwirrung rührt von der Tatsache her, dass in der Mathematik und in vielen anderen gängigen Programmiersprachen Funktionen erlaubt sind, die mehrere Argumente annehmen. In Haskell können Funktionen jedoch nur ein Argument enthalten, und sie können entweder Werte wie a
oder Funktionen wie a -> a
.
Teilweise angewendete Addierfunktion
Wir können eine Teilanwendung verwenden , um das erste Argument zu "sperren". Nachdem wir ein Argument angewendet haben, bleibt eine Funktion übrig, die ein weiteres Argument erwartet, bevor das Ergebnis zurückgegeben wird.
(+) :: Int -> Int -> Int
addOne :: Int -> Int
addOne = (+) 1
Wir können dann addOne
verwenden, um eins zu einem Int
hinzuzufügen.
> addOne 5
6
> map addOne [1,2,3]
[2,3,4]
Rückgabe einer teilweise angewendeten Funktion
Das Zurückgeben von teilweise angewendeten Funktionen ist eine Methode, um prägnanten Code zu schreiben.
add :: Int -> Int -> Int
add x = (+x)
add 5 2
In diesem Beispiel ist (+ x) eine teilweise angewendete Funktion. Beachten Sie, dass der zweite Parameter der Add-Funktion nicht in der Funktionsdefinition angegeben werden muss.
Das Ergebnis des Aufrufs von add 5 2
ist sieben.
Abschnitte
Das Aufteilen ist eine prägnante Methode, um Argumente teilweise auf Infix-Operatoren anzuwenden.
Wenn Sie zum Beispiel eine Funktion schreiben möchten, die am Ende eines Wortes "ing" hinzufügt, können Sie einen Abschnitt verwenden, um eine Funktion präzise zu definieren.
> (++ "ing") "laugh"
"laughing"
Beachten Sie, wie wir das zweite Argument teilweise angewendet haben. Normalerweise können wir die Argumente nur teilweise in der angegebenen Reihenfolge anwenden.
Wir können auch die linke Sektion verwenden, um das erste Argument teilweise anzuwenden.
> ("re" ++) "do"
"redo"
Wir könnten dies äquivalent mit normaler Präfix-Teilanwendung schreiben:
> ((++) "re") "do"
"redo"
Ein Hinweis zur Subtraktion
Anfänger fällen häufig falsch Negationen.
> map (-1) [1,2,3]
***error: Could not deduce...
Das funktioniert nicht, wie -1
als die wörtliche analysiert wird -1
statt der aufgeschnittene Operator -
angewendet auf 1
. Die subtract
existiert, um dieses Problem zu umgehen.
> map (subtract 1) [1,2,3]
[0,1,2]