inferred-type

___ qstntxt ___

Ich bin irgendwie neu in Haskell und ich habe Schwierigkeiten zu verstehen, wie abgeleitete Typen und solche Arbeiten.

%Vor%

Was genau bedeutet das?

%Vor%

Was sind die Unterschiede zwischen diesen?

Und der abgeleitete Typ von

foldr Karte ist [a] - & gt; [a - & gt; a] - & gt; [a]

aber warum ist das so?

Danke!

    
___ qstnhdr ___ Typen in Haskell ___ answer2813690 ___

Wenn Sie das Beispiel von

nehmen %Vor%

Dies bedeutet, dass map zwei Argumente benötigt

  1. Eine Funktion von Typ a nach Typ b
  2. Eine Liste vom Typ a

Und es kommt zurück

  1. Eine Liste von b

Sie können das Muster bereits sehen, aber es wird klarer, wenn wir 'a' und 'b'

ersetzen
  • a = Zeichenfolge
  • b = Int

Also wird diese Typdefinition

sein %Vor%

Nun ist es also eine Funktion, die einen String zurücknimmt und Int und eine Liste von Strings zurückgibt und eine Liste von Ints zurückgibt.

Sagen Sie unsere Funktion, die einen String übernimmt und zurückgibt, und Int ist %code% . %code% verwendet den String, den Sie ihm geben, um ihn in etwas anderes zu konvertieren. Da wir es hier in einen Int-Kontext stellen, wird die Zeichenkette in int

konvertiert %Vor%

Dies wird zu

führen %Vor%

weil %code% die Funktion %code% und Maps für jedes Element der Liste übernimmt (anwendet). Sie müssen nicht %code% sagen, es ist ein Argument wie %code% oder %code% , weil %code% das für Sie erledigt.

Und das ist wirklich alles, was dazu gehört. Der Typ einer Funktion sagt nur, welche Typen sie benötigt und welchen Typ sie zurückgibt. Natürlich gibt es auch Curry, aber dazu wirst du später entweder absichtlich kommen oder nicht! Es bedeutet im Grunde, dass eine Funktion nicht viele Argumente akzeptiert, sondern nur eins. Nehmen wir an, Sie nehmen die Funktion %code% . Wenn Sie %code% auswerten, gibt es eine Funktion zurück, die eine andere Zahl übernimmt, die zu %code% hinzugefügt wird, und da es hier eine andere Zahl gibt, %code% , wird diese verwendet. Sie hätten es als %code% auswerten und weitergeben können, eventuell später die Nummer hinzugefügt. Es ist klarer, wenn Sie nicht die Infix-Syntax von %code% haben. Es hätte %code% geschrieben werden können, also wird diese Anweisung zuerst %code% , was vom Typ ist (vereinfacht! Ich werde hier nicht die Klasse Num-Klasse einführen) %code% . Also %code% (oder %code% ) ist nur eine weitere Funktion, auf die Sie einen Wert anwenden können. An diesem Punkt kann das Ergebnis zu 3 rechnen.

So sieht das in der Praxis aus: (Ignoriere den %code% -Teil hier, wenn er dich verwirrt, es ist ein Konzept, von dem du später mehr erfährst. Ersetze einfach die %code% -Typen hier durch %code% , wenn du willst, und Ignoriere den %code% Teil komplett.)

%Vor%

Und zu Ihrer zweiten Frage: Sie definieren abgeleitete Typen NICHT ALLE. Sie werden "abgeleitet" genannt, weil der Compiler / Interpreter die Typen selbst "leitet" (liest: berechnet), ohne sie explizit zu benennen.

Über die %code% Unterschiede: Sie alle machen genau dasselbe: Reduzieren Sie eine Liste auf einen einzelnen Wert. Der Unterschied zwischen den Funktionen ist lediglich die interne Definition. %code% faltet die Liste von links und %code% macht sie rechts.

Um eine Liste zusammenzufassen, können Sie alle so verwenden ...

%Vor%

Sie sehen, mit Ausnahme von foldl1, liefern Sie eine Funktion zum Falten, einen Startwert (Akkumulator) und eine Liste zum Falten. %code% hat einen eigenen Akku, du gibst ihn nicht selbst.

In der Praxis sollten Sie besser %code% verwenden, da es im Gegensatz zu %code% für BIG-Listen geeignet ist, ohne aufgrund eines Stack-Überlaufs abzustürzen (tee, hee). Und Ausnahme von dieser Regel ist %code% (beachte das "'"!) In %code% - es ist eine strikte Faltung, die auch für große Listen geeignet ist.

Wenn Sie Funktionen ihre Typen selbst geben möchten (wenn Sie sie geschrieben haben), betrachten Sie dieses Beispiel:

%Vor%

Oder auf haskellische Weise

%Vor%

In der ersten Zeile der beiden Beispiele ( %code% ) suchen Sie. So können Sie den Compiler oder Interpreter zwingen, die Funktion zu identifizieren - Sie können sie dann weglassen, und der Compiler / Interpreter wird sie herausfinden (und manchmal sogar besser, als man zuerst denken würde)

    
___ answer2813703 ___

Funktionen in Haskell verwenden eine Notation namens Curry. Eine Definition wie

%Vor%

bedeutet, dass %code% eine Funktion ist, die zwei %code% s akzeptiert und einen Wert vom Typ ganz rechts zurückgibt (der wiederum %code% ist). Genauer gesagt bedeutet currying, dass Sie mit teilweise angewandten Funktionen arbeiten, die Ihnen erlauben, Code wie

zu schreiben %Vor%

Kleinbuchstaben in Typensignaturen weisen auf eine sogenannte -Typ-Variable hin, die als Platzhalter für jeden möglichen Typ angesehen werden kann.

Die Definition

%Vor%

bedeutet also Für alle Typen %code% und %code% , %code% nimmt eine Funktion von %code% bis %code% und eine Liste von %code% , von denen es eine Liste von erzeugt %code% s .

Nehmen wir ein Beispiel

%Vor%

Wir sehen, die angegebene Liste ist eine Liste von %code% , also %code% . Darüber hinaus sollte %code% %code% auf jedes Element anwenden, was ein %code% zurückgibt. Da %code% auf den Typ %code% der Definition passen muss, können wir folgern, dass %code% .

Unser Ausdruck gibt ein %code% zurück, also ist das Ergebnis ein %code% .

Um solche Signaturen noch deutlicher zu machen, können wir sie mit einer ausführlicheren Syntax schreiben

%Vor%

Dies gibt nun explizit an, dass %code% mit allen Typen %code% und %code% arbeiten soll.

Für die Falten werfen Sie einen Blick auf ihre Definitionen . Angesichts des obigen Wissens sollten die Typ-Signaturen selbsterklärend sein, wenn klar ist, was die Funktionen tun sollen.

Beispiel: %code%

Die Signatur von %code% wird.

%Vor%

Sie können diese auch erhalten, indem Sie einfach %code% in den Haskell-Interpreter (GHCi) eingeben.

    
___ tag123types ___ Typen und Typsysteme werden verwendet, um Abstraktionsstufen in Programmen zu erzwingen. ___ tag123haskell ___ Haskell ist eine funktionale Programmiersprache mit starker statischer Typisierung, verzögerungsfreier Auswertung, umfangreicher Parallelitäts- und Parallelitätsunterstützung und einzigartigen Abstraktionsfunktionen. ___ tag123type-interferenz ___ Typ-Inferenz ist der Prozess, bei dem automatisch Typen für Programme abgeleitet werden, wobei Regeln verwendet werden, die von einem Typsystem definiert werden. ___ answer2813662 ___

In Haskell ist eine Kleinschreibung eine Typvariable. Während %code% nur %code% , %code% oder %code% bedeutet, könnte %code% oder %code% oder %code% oder ein anderer Typ bedeuten. Der Schlüssel ist, dass alle %code% s vom selben Typ sind. Und alle %code% s sind vom selben Typ.

Zum Beispiel verwendet %code% als erstes Argument eine Funktion, die eine Variable vom Typ %code% und eine andere vom Typ %code% zurückgibt. Dann gibt %code% eine neue Funktion zurück, die eine Liste vom Typ %code% übernimmt. Diese neue Funktion gibt eine Liste vom Typ %code% zurück.

Angenommen, Sie hätten eine Funktion %code% , die einen Wert zu einer Ganzzahl hinzufügt. %code% würde letztendlich eine Liste [2,3,4] zurückgeben.

Die frühere Definition von %code% mit den ersetzten Typvariablen würde wie folgt aussehen:

%code%

und %code% , BTW, würden wie

aussehen

%code%

Der Grund, warum es lustig geschrieben ist, ist, dass Sie Funktionen teilweise anwenden können. Hier werde ich eine neue Funktion basierend auf der teilweisen Anwendung der Karte machen:

%Vor%

Dann könnten Sie

verwenden %Vor%

würde das gleiche Ergebnis erzeugen

    
___ tag123ermitteltyp ___ typefehler bezieht sich auf die automatische Ableitung des Typs eines Ausdrucks in einer Programmiersprache. ___ answer2813692 ___

Die Kleinbuchstaben in den Typdeklarationen sind Typ Variablen . Das heißt, wenn ein %code% vorhanden ist, muss dies derselbe Typ sein.

Klammerausdrücke (zB %code% ) Teilausdrücke neigen dazu, zu bedeuten, dass die Funktion eine Funktion als einen ihrer Parameter akzeptiert.

Rechteckige Klammern zeigen eine Liste von etwas an.

So akzeptiert %code% diese Argumente:

  • %code% Eine Funktion, die ein Argument
  • akzeptiert
  • %code% eine Liste, in der die erste Argumentfunktion auf
  • wirken kann

und erzeugt %code% eine Liste als Ergebnis.

Wir können %code% auf die gleiche Weise dekodieren:

  • %code% ist eine Funktion, die ein einzelnes Argument
  • akzeptiert
  • %code% ist eine Funktion, die den gleichen Typ wie das Argument der ersten Funktion
  • erzeugt
  • %code% ein Argument des gleichen Typs, das die zweite Funktion verwendet

Haskell kann jedoch eine nette Sache machen, und das heißt, wenn Sie ein Argument weglassen, gibt es eine Funktion zurück, die die verbleibende Signatur hat. Daher wird %code% häufig verwendet, um Funktionen zu ketten.

Nehmen wir an, wir haben 2 Funktionen %code% , die ein Zeichen annehmen und dessen Integer-Repräsentation und %code% zurückgeben, was seinem Argument 32 hinzufügt.

Wenn wir %code% schreiben, hat die Funktion upcaseVal jetzt die Signatur %code% , weil die Funktion %code% sie mit %code% belassen hätte und wir sie in der Funktionsdefinition ersetzen würden.

Also müsste %code% so sein:

  1. Das erste Argument von %code% ist eine Funktion, die 2 Argumente akzeptiert, die %code% ist.
  2. Da die Ausgabe der Funktionen vom selben Typ sein muss wie das zweite Argument ( %code% ), sehen wir das in %code% %code%

Somit ist der letzte Typ:

%Vor%

Aber ich denke, das muss Sie nicht so sehr stören, da der Compiler die meiste Zeit damit beschäftigt ist.

    
___
4
Antworten

Typen in Haskell

Ich bin irgendwie neu in Haskell und ich habe Schwierigkeiten zu verstehen, wie abgeleitete Typen und solche Arbeiten. %Vor% Was genau bedeutet das? %Vor% Was sind die Unterschiede zwischen diesen? Und der abgeleitete Typ von foldr...
11.05.2010, 18:41