Frage
Ich habe eine Frage zu zwei Arten int -> (int -> int) und (int -> int) -> int.Was ist der Unterschied zwischen diesen beiden?
Ich lese hier irgendwo, wo der erste als Funktion interpretiert werden könnte, die eine int eingreift und eine Funktion zurückgibt, die int und int zurückgibt, und eine int-int - int - int - int.Ist das richtig?
Lösung
Der Unterschied zwischen int -> (int -> int)
und int -> int -> int
ist vernachlässigbar (es wäre Ihnen wirklich nur wichtig, wenn Sie mit einer anderen Sprache interagieren müssten).Dies sind Curry-Funktionen, die effektiv zwei Ganzzahlen annehmen und eine Ganzzahl zurückgeben (z. B. hat der eingebaute Additionsoperator einen Typ in dieser Richtung).
Beide unterscheiden sich jedoch stark vom (int -> int) -> int
, der eine -Funktion von Ganzzahlen zu Ganzzahlen übernimmt und eine Ganzzahl zurückgibt.Wie andere erwähnt haben, würde das einzige einfache Beispiel einer solchen Funktion die gegebene Funktion auf einen bestimmten Wert (z. B. fun (f:int->int) -> f 13
) anwenden
Andere Tipps
Gute Frage, ich vermute, dass es funktionell keinen großen Unterschied gibt.Ich habe eine Weile herumgespielt und versucht herauszufinden, wie ich diese beiden Unterschriften überhaupt bekommen kann.(John Palmers let fun1 i = fun j -> i + j
gibt nur int -> int -> int
für mich an)
let add a b = a + b // int -> int -> int
let inc a = add a // int -> (int -> int)
Ich konnte mir kein nicht erfundenes Beispiel für die zweite Signatur vorstellen:
let foo fn : int -> fn 1 // (int -> int) -> int
(Dies beantwortet Ihre Frage nicht direkt, kann aber jemand anderem etwas zum Kauen geben)
Ich kenne F # nicht wirklich, aber es scheint ziemlich intuitiv zu sein (viele andere Sprachen haben die gleichen Vorstellungen).
- Ist eine Funktion, die ein int nimmt und eine Funktion zurückgibt, die ein int nimmt und ein int zurückgibt
- Ist eine Funktion, die eine Funktion übernimmt, die ein int nimmt und ein int zurückgibt, und ein int zurückgibt
Die erste wäre eine Art Curry-Funktion.
Mal sehen, wie Implementierungen aussehen würden:
zuerst
let func1 i = fun j -> i+j
Dies hat eine Signatur von int -> (int -> int)
Beachten Sie, dass func1 2 3
nicht funktionieren sollte
BEARBEITEN: Es stellt sich heraus, dass dies aufgrund der Funktionsweise der Assoziativität tatsächlich in Ordnung ist
aber das ist anders als
let func2 i j= i+j
mit einer Art int -> int -> int
hier ist func2 1 2
in Ordnung
das andere Beispiel, das wir so erstellen können:
let func4 a = a 1
Dies hat eine Signatur des ('t->int) -> u
s. Die Auswahl eines konkreten a
s funktioniert.Beachten Sie, dass func4 1 2
definitiv nicht kompiliert wird