Logische Kombinatoren (d. h. die S-, K-, I-Kombinatoren) sind im Wesentlichen punktfreie Formen von Funktionen, und der Lambda-Kalkül ist äquivalent zur kombinatorischen Logik, also denke ich, dass dies die Antwort ja ist.
Der Kombinator für deine apply2
Funktion ist (wenn ich Dinge richtig lese):
auch bekannt als "Lark", von Raymond Smullyan's Combinatory Birds Seite p>
( Edit-in: ) Es ergibt sich 1 das obige entspricht \f x -> f (x x)
. Nach den Kommentaren von "@gereeter" hier unten ist es tatsächlich bekannt als "Lark", während die in der Frage angeforderte Funktion \f x -> f x x
der "Warbler" aus dem oben genannten Buch ist (aka der "W" Kombinator ), W f x = S(S(K(S(KS)K))S)(KK)SI f x = S(S(KB)S)(KK)SI f x = CSI f x = SfIx = f x x
.
1 hier:
%Vor%
Wie bereits erwähnt, kann jeder Lambda-Term mit einem geeigneten festen Satz von Kombinatoren in eine Form umgewandelt werden, die nur diese Kombinatoren verwendet und die Funktion verwendet - keine Lambda-Abstraktion (also keine Variablen). Der bekannteste Satz von Kombinatoren ist S
und K
. Se Kombinatorische Logik / Vollständigkeit der S-K-Basis zur Beschreibung des Verfahrens. Die Kombinatoren sind definiert als
Manchmal ist der Identity-Kombinator I
enthalten, aber er ist redundant als I = S K K
.
Interessanterweise können Sie das sogar mit einem einzigen Kombinator tun. Die Sprache Iota verwendet
%Vor%und es kann gezeigt werden, dass
%Vor% So können wir jeden Lambda-Ausdruck in einen binären Baum ohne andere Informationen als seine Form umwandeln (alle Blätter enthalten U
und die Knoten stellen die Funktionsanwendung dar).
Wenn wir jedoch ein wenig effizient sein und eine vernünftige Konvertierung durchführen wollen, ist es hilfreich, I
zu verwenden und zwei weitere redundante Kombinatoren einzuführen, die B
und C
heißen:
Hier ändert C
die Reihenfolge der Argumente von f
und B
ist die Funktionszusammensetzung.
Diese Ergänzung reduziert die Länge der Ausgabe erheblich.
Tatsächlich enthält Haskell bereits all diese Standardkombinatoren in irgendeiner Form. Insbesondere:
%Vor% wobei pure
, <*>
und <$>
Funktionen aus der Klasse Applicative
funktors sind, die wir hier für die Leser-Monade (->) r
spezialisieren.
In Ihrem Fall könnten wir also
schreiben %Vor% Bei der Eliminierung der Abstraktion versuchen wir einen Term der Form λx -> M :: r -> a
(wobei r
der Typ von x
und a
der Typ von M
ist) in ein Formular ohne% zu konvertieren Code%. Dies geschieht durch rekursives Verarbeiten von x
, und wir konvertieren anschließend jeden Unterbegriff vom Typ M
(möglicherweise mit b
) in eine Funktion vom Typ x
(ohne r -> b
) und kombinieren dann diese Unterbegriffe zusammen. Und genau dafür ist die Reader-Monade gedacht: Funktionen des Typs x
miteinander zu kombinieren.
Weitere Einzelheiten finden Sie in The Monad Reader, Ausgabe 17 : The Reader Beseitigung von Monaden und Abstraktionen .
Für den Aufbau von Datenstrukturen verwenden wir einfach ihre Konstruktoren, hier gibt es kein Problem.
Um sie zu dekonstruieren, brauchen wir einen Weg, den Mustervergleich zu vermeiden. Dies muss ein Compiler beim Kompilieren eines funktionalen Programms tun. Eine solche Vorgehensweise ist in Implementierung funktionaler Programmiersprachen beschrieben Kapitel 5: Effiziente Kompilierung des Mustervergleichs. Die Idee ist, dass wir für jeden Datentyp eine case -Funktion haben, die beschreibt, wie der Datentyp dekonstruiert (gefaltet) wird. Zum Beispiel für lists r -> something
, für foldr
und Either
, und für 4-Tupel wäre es
usw. Also fügen wir für jeden Datentyp seine Konstruktoren hinzu, die Funktion des Dekonstruierens von case und kompilieren Muster in diese Funktion.
Als Beispiel wollen wir
ausdrücken %Vor% Dies kann mit either
ausgedrückt werden:
und dann mit den oben besprochenen Kombinatoren konvertiert:
%Vor%Sie können bestätigen, dass es tatsächlich das tut, was wir wollen.
Siehe auch System F-Datenstrukturen , die beschreiben, wie Datenstrukturen direkt als Funktionen codiert werden können, wenn wir
Ja , wir können einen festen Satz von Kombinatoren konstruieren und dann jede Funktion in einen punktfreien Stil umwandeln, der nur diese Kombinatoren und Funktionsanwendungen verwendet.
Es gibt viele Funktionen, die aussehen, als wären sie nicht, aber in einem Punkt-freien Stil ausdrückbar, aber um einen zu bekommen, der nicht ist, könnten Sie schnell einen definieren, der mit extrem großen Tupeln arbeitet, wo es keine gibt. t irgendwelche Standardfunktionen.
Ich denke, diese Art von Ding ist weniger wahrscheinlich punktfrei auszudrücken, nicht wegen der Komplexität, sondern weil es nicht viele Funktionen von Tupeln dieser Größe gibt:
%Vor%Ihr Beispiel:
%Vor% Es ist join
in der Leser-Monade ((->) b)
also in diesem Fall
%Vor%Viele weitere Funktionen, als wir erwarten, haben point-freie Versionen, aber einige point-free Ausdrücke sind ein komplettes Durcheinander. Manchmal ist es besser, explizit als knapp zu sein.
Tags und Links haskell lambda-calculus pointfree
Zuerst werde ich Ihnen sagen, wie Sie Ihre RewriteRule lesen können:
Sie beginnen mit dem ersten (oder nächsten) RewriteRule-Eintrag:
%code%
Der erste Parameter ist ein regulärer Ausdruck, der der angeforderten URL entsprechen kann. %code% stimmt mit allem überein und speichert dieses "alles" in einer Variablen, die später verwendet werden kann.
Nur wenn vorhergehende RewriteCond-Einträge vorhanden sind, werden sie als nächstes ausgewertet:
%code%
%code% ist ein Verweis auf den Inhalt, der in den ersten Klammern von RewriteRule gefunden wurde. Dies wird mit dem zweiten Parameter verglichen, der ein regulärer Ausdruck ist, der mehrere explizite Namen angibt, und der %code% negiert den Ausdruck, z. Diese Regel erlaubt die Ausführung der RewriteRule nur, wenn die Regex nicht übereinstimmt. Wenn diese Bedingung wahr zurückgibt, wird die nächste Bedingung betrachtet.
%code%
Wenn der angeforderte Dateiname keine echte Datei auf der Festplatte ist, ist diese Bedingung wahr.
%code%
Wenn der angeforderte Dateiname kein echtes Verzeichnis ist, ist diese Bedingung wahr.
Nur wenn alle diese Bedingungen zutreffen (sie sind zusammen mit AND verkettet), kommen wir zurück zur Umschreiberegel:
%code%
Das Ergebnis dieses Umschreibschritts wird als zweiter und dritter Parameter definiert. %code% wird wieder wie für den Inhalt der Übereinstimmung verwendet, und die Parameter definieren, dass diese Regel, wenn sie anfänglich übereinstimmt, die letzte Regel (L) ist und dass jede im Umschreibeziel definierte Abfragezeichenfolge an eine beliebige angehängt wird Abfragezeichenfolge in der ursprünglichen URL (QSA).
Kritik:
Das übliche Umschreiben für MVC-Frameworks versucht, so performant wie möglich zu sein. Ihre Umschreibungsbedingungen müssen alle für eine erfolgreiche Umschreibung ausgewertet werden. Die Option wird nur angehalten, wenn einer der RewriteCond-Werte false zurückgibt. Jede Anforderung, die neu geschrieben wird, unterliegt zahlreichen CPU-intensiven Tests. Zuerst die RewriteRule Regex, dann die Regex in der ersten RewriteCond, gefolgt von zwei Harddisk-Tests auf dem Dateisystem für die Datei Existenz.
Auf der anderen Seite scheint der erste RewriteCond unnötig zu sein. Es prüft auf bestimmte Namen und bricht das Neuschreiben ab. "index.php" sollte vom zweiten RewriteCond erkannt werden, da es sich um eine existierende Datei handelt (wie würde das Umschreiben funktionieren, wenn nicht). Alles, was mit "Ressourcen" beginnt, wird ebenfalls angepasst, aber wahrscheinlich nicht aus den gleichen Gründen: Vorhandene Ressourcen werden vom zweiten RewriteCond gefunden. Zuletzt die Datei "robots.txt". Es ist immer eine gute Idee, eine zu haben, möglicherweise empty, wenn Sie 404 vermeiden möchten, wenn Roboter Ihre Site holen.
Da Sie nichts in der Abfragezeichenfolge ändern, wird die [QSA] -Direktive nicht benötigt.
Verbesserungen:
%Vor%Die erste RewriteRule stimmt mit dem gesamten angeforderten Pfad überein. Die beiden RewriteCond sind mit [OR] verbunden, sodass der erste RewriteCond, der True zurückgibt, die weitere Auswertung abbricht. Der erste RewriteCond testet, ob die angeforderte Datei existiert. Wenn es existiert, wird true zurückgegeben und die Verarbeitung kehrt zur ersten RewriteRule zurück. Der Zielausdruck ist "-", was "nicht neu schreiben" bedeutet. Der [L] stoppt die weitere Verarbeitung der Umschreibregeln. Am Ende haben wir für eine existierende Datei nur einen Regex- und einen Dateisystemtest, und danach wird diese existierende Datei an den Browser gesendet.
Wenn keine Datei gefunden wurde, werden die erste RewriteRule und RewriteCond nicht ausgelöst, daher wird [L] dort den Prozess nicht stoppen. Also wird die zweite RewriteRule ausgeführt. Dieser ist unconditional, und die Regex ist die gleiche wie zuvor, stimmt mit allem überein und schreibt es in "index.php" um.
Dieses Umschreiben ruft Ihre index.php nicht auf, wenn eine Datei existiert, einschließlich /forum/login.php.
Sie können die zweite in %code% ändern, wenn Sie weiterhin %code% statt %code% analysieren möchten.
Meine Seite leitet aufgrund meiner .htaccess-Datei, die wie folgt eingestellt ist, nicht um:
%Vor%Ich benutze dieses Setup für mein MVC Framework, also erhalte ich URLs wie %code% , aber wenn ich nach /forum/login.php umadressiere, schneidet es nach / forum /.
Wie kann ich das als Ausnahme hinzufügen, damit ich nach %code%
umleiten kann?Ich habe eine andere .htaccess in meinem / forum / Verzeichnis gefunden, könnte das auch das Problem verursachen?
%Vor%Versuchen Sie es mit:
%Vor%Und das:
%Vor%