Den Typfehler verstehen: "erwartete Signatur Int * Int-Int, aber Int * Int-Int"

8

Die Kommentare zu Steve Yegge ist über serverseitiges JavaScript begann die Diskussion über die Vorzüge von Typ-Systemen in Sprachen und diese Kommentar beschreibt:

  

... Beispiele von H-M Stilsystemen, wo Sie Dinge wie:

bekommen können %Vor%

Können Sie ein Beispiel für eine Funktionsdefinition (oder zwei?) und einen Funktionsaufruf geben, der diesen Fehler erzeugt? Das sieht so aus, als wäre es in einem groß angelegten Programm ziemlich schwer zu debuggen.

Habe ich vielleicht auch einen ähnlichen Fehler in Miranda gesehen? (Ich habe es nicht in 15 Jahren verwendet und so ist meine Erinnerung daran vage)

    
devstopfix 27.11.2008, 20:36
quelle

3 Antworten

8

Ich würde Yegges (und Ola Binis) Meinungen zur statischen Typisierung mit einem Körnchen Salz nehmen. Wenn Sie wissen, was die statische Typisierung Ihnen bringt, erfahren Sie, wie das Typsystem der gewählten Programmiersprache funktioniert.

IIRC, ML verwendet die '*' Syntax für Tupel. & lt; Typ & gt; * & lt; Typ & gt; ist ein Tupel-Typ mit zwei Elementen. Also hätte (1, 2) int * int type.

Sowohl Haskell als auch ML benutzen - & gt; für Funktionen. In ML int * int - & gt; int wäre der Typ einer Funktion, die ein Tupel von int und int annimmt und sie einem int zuordnet.

Einer der Gründe, warum Sie vielleicht einen Fehler sehen, der dem Ola ähnelt, wenn Sie aus einer anderen Sprache zu ML kommen, ist, wenn Sie versuchen, Argumente mit Klammern und Kommas zu übergeben, wie in C oder Pascal eine Funktion, die zwei Parameter akzeptiert.

Das Problem ist, dass funktionale Sprachen im Allgemeinen Funktionen von mehr als einem Parameter als Funktionen, die Funktionen zurückgeben, modellieren; Alle Funktionen haben nur ein Argument. Wenn die Funktion zwei Argumente benötigt, nimmt sie stattdessen ein Argument und gibt eine Funktion eines einzelnen Arguments zurück, das das Endergebnis zurückgibt, und so weiter. Um all dies lesbar zu machen, wird die Funktionsanwendung einfach durch Verbindung ausgeführt (d. H. Die Ausdrücke nebeneinander platzieren).

Also, eine einfache Funktion in ML (Anmerkung: Ich benutze F # als meine ML) sieht vielleicht ein bisschen wie folgt aus:

%Vor%

Es hat Typ:

%Vor%

(Eine Funktion, die eine Ganzzahl annimmt und eine Funktion zurückgibt, die selbst eine Ganzzahl annimmt und eine Ganzzahl zurückgibt.)

Wenn Sie es jedoch naiv mit einem Tupel aufrufen:

%Vor%

... Sie erhalten einen Fehler, weil Sie ein int * int an etwas übergeben haben, das ein int erwartet.

Ich erwarte, dass dies das "Problem" ist, an dem Ola versuchte, Verärgerungen zu provozieren. Ich glaube nicht, dass das Problem so schlimm ist wie er denkt; Sicherlich ist es in C ++ - Vorlagen viel schlimmer.

    
Barry Kelly 27.11.2008, 20:55
quelle
4

Es ist möglich, dass es sich um einen schlecht geschriebenen Compiler handelte, bei dem keine Klammern eingefügt wurden, um Fehlermeldungen zu disambiguieren. Insbesondere erwartete die Funktion ein Tupel von int und gab ein int zurück, aber Sie übergaben ein Tupel von int und eine Funktion von int an int . Konkreter (in ML):

%Vor%

Dies erzeugt einen Typfehler ähnlich dem Folgenden:

  

Erwarteter Typ int * int -> int , hat den Typ int * (int -> int)

erhalten

Wenn die Klammern weggelassen werden, kann dieser Fehler ärgerlich mehrdeutig sein.

Es ist erwähnenswert, dass dieses Problem bei Hindley-Milner alles andere als spezifisch ist. Tatsächlich kann ich mir keine seltsamen Fehler vorstellen, die spezifisch für H-M sind. Zumindest keine wie das angegebene Beispiel. Ich vermute, dass Ola nur Rauch geblasen hat.

    
Daniel Spiewak 27.11.2008 21:17
quelle
3

Da viele funktionale Sprachen es Ihnen erlauben, Typnamen auf die gleiche Weise zu binden, wie Sie Variablen neu binden können, ist es ziemlich einfach, mit einem solchen Fehler zu enden, besonders wenn Sie etwas generische Namen für Ihre Typen verwenden (zB% co_de) %) in verschiedenen Modulen. Hier ist ein einfaches Beispiel in OCaml:

%Vor%

Was ich hier getan habe, ist, den Typbezeichner t an einen neuen Typ zu binden, der mit dem integrierten int -Typ inkompatibel ist. Mit ein wenig mehr Aufwand können wir mehr oder weniger den gleichen Fehler wie oben erhalten:

%Vor%     
Chris Conway 07.06.2009 15:14
quelle

Tags und Links