Ich versuche gerade, Haskell zu lernen, aber ich habe Mühe, die Syntax zu verstehen. Nehmen wir zum Beispiel die Funktion map
:
Ich verstehe, was die Funktion macht, und dass map
eine Funktion f :: s -> t
als Parameter hat. Aber ich lese map :: (s -> t) -> [s] -> [t]
als "map ist eine Funktion, die ein Funktionsmapping von s auf t auf s und dann auf t" abbildet, was offensichtlich falsch ist. Könnte jemand das für mich klären?
Der Typ (s -> t) -> [s] -> [t]
kann auf zwei Arten gelesen werden. Eine Möglichkeit besteht darin, sie als eine Funktion von zwei Argumenten zu behandeln, wobei die erste eine Funktion vom Typ s -> t
und die zweite eine Liste vom Typ [s]
ist. Der Rückgabewert ist vom Typ [t]
.
Der andere Weg ist zu verstehen, dass Funktionspfeile rechtsassoziativ sind, also entspricht der Typ (s -> t) -> ([s] -> [t])
. Unter dieser Interpretation ist map
eine Funktion, die eine Funktion von Element zu Element s -> t
übernimmt und sie in eine Funktion von Liste zu Liste [s] -> [t]
umwandelt.
Wenn Sie die Funktion verwenden, können Sie sich auch map foo xs
vorstellen, wenn Sie die Funktion map
auf die beiden Argumente foo
und xs
anwenden. Oder, da die Funktionsanwendung links -assoziativ ist, können Sie sie als (map foo) xs
betrachten, indem Sie map
auf das einzelne Argument foo
anwenden, um eine neue Funktion zurückzugewinnen, die Sie dann auf% anwenden. co_de%.
Da Haskell-Funktionen
Es kann hilfreich sein, einen Aliastyp zu definieren, um etwas deutlicher zu machen, was all diese Pfeile und Klammern tun:
%Vor% Nun können Sie die Signatur von map
wie folgt schreiben:
welches, wenn Sie mit Java oder C ++ oder was auch immer vertrauter sind, syntaktisch etwas mehr wie folgt aussieht:
%Vor% Man kann sich das so vorstellen: map
nimmt eine Funktion und eine Liste und gibt eine andere Liste zurück. Da Funktionen jedoch in Haskell curried sind, müssen Sie nicht alle Parameter gleichzeitig übergeben. Sie könnten damit davonkommen, dass Sie nur teilweise auf das erste Argument anwenden, indem Sie map
anwenden. Also ist seine Typensignatur eher wie folgt:
... was, wenn Sie map
mit nur einem fun
-Argument aufrufen, Ihnen etwas gibt, das ungefähr so aussieht:
Also jetzt zurück zu Haskell: Sie können map :: (s -> t) -> [s] -> [t]
entweder als:
map
nimmt eine Funktion von s zu t und eine Liste von s und gibt eine Liste von zurück t "map
nimmt eine Funktion von s zu t und wandelt sie in eine Funktion von einer Liste von s zu a Ersteres ist in Ordnung; Letzteres ist hilfreicher.
Wie wäre es mit "map" ist eine Funktion, die eine (Funktion von s nach t) über eine (Liste von s) abbildet, die eine (Liste von t) ergibt? Das ist eine direkte Übersetzung der Typ-Signatur ins Englische (wenn auch nicht sehr elegantes Englisch).
Lesen Sie die Signatur vom Ende: -> [t]
bedeutet gibt eine Liste von t
zurück. Der Rest ist "normale" Parameter.
Also nimmt map
eine Funktion, die von s
eine t
erstellt, und eine Liste von s
.
Jetzt ist es einfach: Nimm eine Funktion s->t
, verwende sie für jedes Element von [s]
und das Ergebnis davon ist [t]
.
Tags und Links haskell