Javascript currying

8

Ich versuche eine Curry-Funktion zu erstellen, die auf jede Funktion angewendet werden kann und eine andere zurückgibt. mit 1 der Argumente angewendet. Eigenschaften, die ich haben möchte:

  1. Wenn die Funktion nur ein Argument hat, sollte die Curry-Funktion einen Wert zurückgeben: Fa); Curry (f, x) = f (x);
  2. Wenn die Funktion viele Argumente hat, sollte currey die Curry-Funktion retrunen: g (a1, a2, ..., aN); Curry (g, x) = g2 (a2, ..., aN): g2 (a2, ... aN) = g (x, a2, ..., aN)
  3. Die Länge der Curry-Funktion sollte "nach Bedarf" funktionieren g.length = N = & gt; Curry (g, x) .Länge = N-1

Es gibt einige Implementierungen von Curry in Prototype Framework und Diskussionen in einem Blog . Aber diese Implementierung ist nicht gut, weil sie nicht gut auf Funktionen mit nur einem Argument funktioniert (1), und auch das Attribut 'length' der Funktion 'function' ist 0 (3).

Für die erste Eigenschaft gibt es eine einfache Implementierung:

%Vor%

Aber ich weiß nicht, wie man mit der dritten Regel arbeitet, d. h. Funktion kann als innere Funktion konstruiert werden, da es eine verschachtelte Lexikalische Umgebung geben wird und f:

verwendet werden kann %Vor%

aber in diesem Fall werde ich nicht mehr in der Lage sein, Parameter explizit festzulegen. Auf der anderen Seite kann die Funktion mit der Anweisung 'new Function' erstellt werden, ähnlich wie:

%Vor%

Aber in dieser Situation werden f und x nicht gebunden, weil anonyme Funktion erzeugt wird Globale Lexikalische Umgebung.

Also die Fragen:

  1. Gibt es eine Möglichkeit, die Parameteranzahl beim Erstellen einer Funktion mit dem Funktionsschlüsselwort?
  2. explizit festzulegen
  3. gibt es eine Möglichkeit, die Umgebung der Funktion zu setzen, die mit der Anweisung 'new Function' erstellt wurde?
  4. uns da einen Weg, mein Problem auf andere Weise zu lösen?
qnikst 11.03.2011, 13:22
quelle

4 Antworten

6

Wie die Functional -Bibliothek dies implementiert, müssen Sie die Parameter, die an "curry ()" übergeben werden, als die ersten Parameter, die übergeben werden sollen. Das Funktionsergebnis der Operation "curry" nimmt dann alle zusätzlichen Parameter an, die beim Aufruf übergeben werden, und fügt sie am Ende der Argumentliste hinzu. Es macht sich überhaupt keine Gedanken über die Länge der Argumentliste, weil das in JavaScript im Allgemeinen keine feste Sache ist, also gibt es wirklich keinen Sinn.

Also:

%Vor%

Also ruft:

%Vor%

wird wie ein Anruf sein:

%Vor%

Functional hat eine andere Funktion namens "partial ()", die eine kontrolliertere Substitution von Parametern ermöglicht. Wenn Sie "partial ()" aufrufen, übergeben Sie ein Dummy-Argument ("_"), um anzugeben, wo sich "Löcher" in der Argumentliste befinden:

%Vor%

Diese beiden Parameter "_" bedeuten, dass der resultierende "partialFunc" zuerst zwei Argumente, die an ihn übergeben wurden, in diese Schlitze in der Argumentliste fallen lassen sollte:

%Vor%

ist also genau wie das Anrufen:

%Vor%

Ich empfehle Ihnen wärmstens, diese Bibliothek zu bekommen und sich den Code anzusehen. Es ist überraschend prägnant und klar.

Noch eine Sache: Es ist wichtig zu beachten, dass JavaScript nicht eine "lazy-evaluation" -Sprache ist, sondern wirklich dasselbe ist wie die "curry" -Operation in einer faulen funktionalen Sprache wie Haskell. Der Unterschied ist, dass die Argumente zur "Curry-Zeit" ausgewertet sind und daher in das Ergebnis "gekocht" werden. In einer faulen Sprache sind die Dinge anders.

    
Pointy 11.03.2011, 13:34
quelle
3
%Vor%     
gnarf 11.03.2011 13:39
quelle
2

Seit Jahren verwende ich einen Funktionsprototyp für Curry, der so aussieht:

%Vor%

Vielleicht wird es auch Ihren Bedürfnissen entsprechen.

Sie benutzen es einfach so:

%Vor%

Es wird mit einer beliebigen Anzahl von Argumenten funktionieren.

    
Martin Jespersen 11.03.2011 14:05
quelle
0
%Vor%     
Eric.K.Yung 26.12.2012 20:08
quelle

Tags und Links