Haskell: Anfänger Funktion Syntax Verwirrung

7

Ich versuche gerade, Haskell zu lernen, aber ich habe Mühe, die Syntax zu verstehen. Nehmen wir zum Beispiel die Funktion map :

%Vor%

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?

    
ryyst 26.10.2011, 20:16
quelle

4 Antworten

17

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 sind, sind dies nur zwei Möglichkeiten, genau dasselbe zu sehen.

    
hammar 26.10.2011, 20:28
quelle
2

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:

%Vor%

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:

%Vor%

... was, wenn Sie map mit nur einem fun -Argument aufrufen, Ihnen etwas gibt, das ungefähr so ​​aussieht:

%Vor%

Also jetzt zurück zu Haskell: Sie können map :: (s -> t) -> [s] -> [t] entweder als:

lesen
  • " 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 Liste von t "

Ersteres ist in Ordnung; Letzteres ist hilfreicher.

    
mergeconflict 26.10.2011 21:16
quelle
1

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).

    
Daniel Fischer 26.10.2011 20:22
quelle
1

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] .

    
9000 26.10.2011 20:36
quelle

Tags und Links