Warum ist meine durch Reduzieren von Renditen implementierte Funktionszusammensetzung ein Abschluss?

user6445533

Ich möchte eine Kompositionsfunktion für n-Funktionen aus Reduzieren / Falten ableiten, aber es funktioniert nicht wie erwartet:

$id = function ($x) {
  return $x;
};

$comp = function ($f) {
  return function ($g) use ($f) {
    return function ($x) use ($f, $g) {
      return $f($g($x));
    };
  };
};

$fold = function ($f, $acc) {
  return function ($xs) use ($f, &$acc) {
    return array_reduce($xs, $f, $acc);
  };
};

$compn = function($fs) {/* apply $fold here */};

$inc = function ($n) {
  return $n + 1;
};

$fold($comp, $id) ([$inc, $inc, $inc]) (0); // yields a closure instead of 3

Ich habe die gleiche Funktion in Javascript implementiert und es funktioniert. Ich benutze PHP 7.0.8 cli. Ich weiß nicht viel über PHP, daher übersehen ich wahrscheinlich etwas.

Vielen Dank

Ihr $compist Curry , und natürlich haben Sie festgestellt, dass PHPs native array_reduceerwartet, dass die Funktion mehrere Parameter akzeptiert - eine schnelle Anwendung von uncurrynimmt Ihnen einige Schmerzen, aber Sie müssen weiterlesen, wenn Sie sehen möchten, wie dies insgesamt verbessert werden kann. ..


nach PHPs bescheidener Meinung ...

Die Verwendung von uncurry reicht aus, aber Sie werden Ihr Programm wahrscheinlich nicht mögen, wenn alle Funktionen als $benannte Variablen definiert sind. Ich sehe viele kleine Probleme bei der Verwendung dieses Stils.

PHP hat einen aufrufbaren "Typ", der die Dinge ein wenig PHP-artiger macht - benutzerdefinierte Funktionen (einschließlich Funktionen höherer Ordnung) sollten mit call_user_func und call_user_func_array aufgerufen werden

namespace my\module;

function identity ($x) {
  return $x;
}

function comp ($f) {
  return function ($g) use ($f) {
    return function ($x) use ($f, $g) {
      return call_user_func ($f, call_user_func ($g, $x));
    };
  };
}

function uncurry ($f) {
  return function ($x, $y) use ($f) {
    return call_user_func (call_user_func ($f, $x), $y);
  };
}

function fold ($f, $acc) {
  return function ($xs) use ($f, $acc) {
    return array_reduce ($xs, uncurry ($f), $acc);
  };
}

Jetzt compnfunktioniert Ihre mit variadic Schnittstelle wie erwartet

function compn (...$fs) {
  return fold ('comp', 'identity') ($fs);
}

function inc ($x) {
  return $x + 1;
}

echo compn ('inc', 'inc', 'inc') (0); // 3

Es funktioniert aber auch mit anonymen Funktionen

$double = function ($x) { return $x + $x; };

echo compn ($double, $double, 'inc') (2); // 12

Funktionscode, modulares Programm

Wenn Ihre Funktionen mithilfe der functionSyntax deklariert wurden , können Sie sie in andere Bereiche Ihres Programms importieren

// single import
use function my\module\fold;

// aliased import
use function my\module\fold as myfold;

// multiple imports
use function my\module\{identity, comp, compn, fold};

Und jetzt müssen Sie useIhren Code nicht jedes Mal mit -blocks verunreinigen, wenn Sie eine Ihrer Funktionen verwenden möchten

// before
$compn = function (...$fs) use ($fold, $comp, $id) {
  return $fold($comp, $id) ($fs);
};

// after
function compn (...$fs) {
  return fold ('comp', 'id') ($fs);
}

Wenn es um das Debuggen geht, bieten die genannten Funktionen zweifellos auch hilfreichere Stack-Trace-Nachrichten


relevant, aber unwichtig

PHP hat andere Gründe für das Hinzufügen des aufrufbaren Typs, aber diejenigen, die Sie sicher nicht betreffen, da sie OOP-bezogen sind - z.

Klassenmethodenaufrufe

// MyClass::myFunc (1);
call_user_func (['MyClass', 'myFunc'], 1);

Objektmethodenaufrufe

// $me->myfunc (1);
call_user_func ([$me, 'myfunc'], 1);

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Warum ist ein FnOnce-Abschluss ein Schritt?

Warum führt meine implementierte_Funktion () zu NameError: Der globale Name 'Derivativ' ist nicht definiert?

Vereinheitlichung von OCaml-Mustern durch Funktionszusammensetzung

Warum stürzt meine App ab, wenn ein NSPanel durch Drücken von Escape geschlossen wird?

Warum funktioniert meine Prüfung, wenn ein Funktionsargument nicht von einem bestimmten Typ ist, nicht?

Warum ist "Reduzieren" ein Infix-Operator in Chapel?

Warum ist meine Ausgabe keine durch Kommas getrennte Liste?

Warum ist Java durch meine Verwendung von Long.parseLong (String s, int radix) mit dieser langen Binärzahl beleidigt?

Ist jede Funktion ein Abschluss?

Wird durch die Verwendung von 'bind' bei der Rückgabe einer Funktion ein Abschluss erstellt?

Warum denkt React, dass meine Klassenmethode ein Hook ist?

Warum ist meine ytdl-Info des Thumbnails ein Objekt?

Was ist in PHP ein Abschluss und warum wird der Bezeichner "use" verwendet?

Warum ist diese MySQL-Abfrage langsamer, nachdem ein vollständiger Tabellenscan durch einen Scan von `type=ref` ersetzt wurde?

Warum ist ein Teil von Viewmodel Null?

Warum ist meine Implementierung von numpy.random.choice schneller?

Warum ist meine Implementierung von numpy.random.choice schneller?

Warum ist meine Textausgabe von next () und prev () falsch?

Warum ist diese Version von strrev schneller als meine?

Ich verstehe nicht, warum meine Antwort von Hand anders ist

Warum die durch ein Listenverständnis erzeugte Liste leer ist

Warum ist PREFETCHNTA durch "muss ein Rückschreibspeichertyp sein" qualifiziert?

Warum gibt meine Methode ein Array von Nullen zurück?

Warum erhält meine Containerkomponente ein Statusobjekt von anderen Reduzierern?

Warum geht meine Testroute zum Hinzufügen von Freunden in insomina mit 200 OK durch, aber sie ist nicht verschachtelt, wenn ich anrufe, um alle Benutzer zu erhalten?

Ist unsicher meine einzige Möglichkeit, einen Verweis auf diese Methode zu übergeben, wenn ein Abschluss erwartet wird?

Warum ist meine Implementierung von selectionSort schneller als meine Implementierung von bubbleSort?

Was ist der Unterschied zwischen dem Kombinieren von Arrays durch Reduzieren oder Verbinden?

So reduzieren Sie ein Blatt durch Pivotieren von Zeilen in CSV-Daten

TOP Liste

  1. 1

    Modbus Python Schneider PM5300

  2. 2

    Glassfish v3.0.1 im Vergleich zu Oracle GlassFish Server 3.0.1 - Gibt es einen technischen Grund, die kommerzielle Version zu verwenden?

  3. 3

    Wie schließe ich mehrere Ordner mit der Variablen EXTRA_ARGS aus?

  4. 4

    Wie kann eine gleichmäßige Lastverteilung in ElasticSearch mit Indizes mit unterschiedlicher Anzahl von Shards erreicht werden?

  5. 5

    Wie kann man eine Multi-Container-Anwendung in Steuerkarten erstellen?

  6. 6

    ElasticSearch - Knotensperren konnten nicht abgerufen werden

  7. 7

    Python: Spalten mit demselben Namen zusammenführen, wobei der Mindestwert beibehalten wird

  8. 8

    Elasticsearch startet nicht nach dem Laden in viele Daten

  9. 9

    Ärgerliches Problem mit yaml, das ich nicht lösen kann

  10. 10

    Wie Verwenden von Httpclient mit jedem SSL-Zertifikat, egal wie „schlecht“ es ist

  11. 11

    Wie vergleicht man scala.xml-Knoten richtig?

  12. 12

    ElasticSeach Auto Complete mit dem Vervollständigungsvorschlag, um das vollständige Dokument zurückzugeben

  13. 13

    Wie füge ich eine Spalte in einer Zeile in der Ansible Jinja2-Vorlage mit der for-Schleife hinzu?

  14. 14

    HTTPS-Verbindung mit Moneris-Servern in Curl

  15. 15

    Unity Build-Fehler: Der Name 'EditorUtility' ist im aktuellen Kontext nicht vorhanden

  16. 16

    Bester Crawler, um festzustellen, ob er mit Technologien gebaut wurde?

  17. 17

    So erhalten Sie eine gleichmäßige Höhe für alle Eingabefelder

  18. 18

    Wie kann ich den Kaskadenmodus global einstellen?

  19. 19

    Eclipse Oxygen - Projekte verschwinden

  20. 20

    Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

  21. 21

    ElasticSearch BulkShardRequest ist aufgrund von org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor fehlgeschlagen

heißlabel

Archiv