Lemma: Unter der Annahme einer Eta-Äquivalenz haben wir das (\x -> ⊥) = ⊥ :: A -> B
.
Beweis: ⊥ = (\x -> ⊥ x)
durch Eta-Äquivalenz und (\x -> ⊥ x) = (\x -> ⊥)
durch Reduktion unter dem Lambda.
Der Haskell 2010-Bericht, Abschnitt 6.2, spezifiziert die seq
Funktion durch zwei Gleichungen:
seq :: a -> b -> b seq ⊥ b = ⊥ seq ab = b, wenn a ≠ ≠
Es wird dann behauptet "Folglich ist ⊥ nicht dasselbe wie \ x -> ⊥, da seq verwendet werden kann, um sie zu unterscheiden."
Meine Frage ist, ist das wirklich eine Folge der Definition von seq
?
Das implizite Argument scheint zu sein, dass seq
wenn nicht berechenbar wäre seq (\x -> ⊥) b = ⊥
. Ich konnte jedoch nicht beweisen, dass eine seq
solche nicht berechenbar wäre. Es scheint mir so einseq
ob es sowohl monoton als auch kontinuierlich ist, was es in den Bereich der Berechenbarkeit bringt.
Ein Algorithmus, der für für einige zu suchen , indem er versucht, wie Seq funktionieren könnte implementieren , x
wo f x ≠ ⊥
durch die Domäne aufzuzählen , f
beginnend mit ⊥. Obwohl eine solche Implementierung, selbst wenn sie überhaupt möglich ist, ziemlich haarig wird, wenn wir sie seq
polymorph machen wollen .
Gibt es einen Beweis dafür , dass es keine berechenbaren ist , seq
die angibt , (\x -> ⊥)
mit ⊥ :: A -> B
? Alternativ gibt es einige Bau , seq
dass sich identifizieren (\x -> ⊥)
mit ⊥ :: A -> B
?
quelle
seq
seq
Beachten Sie, dass die von
seq
Ihnen angegebene Spezifikation nicht deren Definition ist. So zitieren Sie den Haskell-Bericht: "Die Funktionsfolge wird durch die folgenden Gleichungen definiert : [und dann die von Ihnen angegebenen Gleichungen]".Ein solches Verhalten würde die Spezifikation von verletzen
seq
.Wichtig ist, dass
seq
es polymorphseq
ist und nicht in Form von Dekonstruktoren (Projektionen / Mustervergleich usw.) für einen der beiden Parameter definiert werden kann.Wenn
seq' (\x -> ⊥) b
, könnte man meinen, wir könnten den ersten Parameter (der eine Funktion ist) auf einen bestimmten Wert anwenden und dann ⊥ ausgeben. Aber,seq
kann niemals den ersten Parameter mit einem Funktionswert identifizieren (auch wenn es eine längeren Verwendung sein geschiehtseq
) wegen seines parametrischen polymorphen Typs. Parametrizität bedeutet, dass wir nichts über die Parameter wissen. Außerdemseq
kann man niemals einen Ausdruck nehmen und entscheiden "ist das ⊥?" (vgl. das Halting-Problem),seq
kann nur versuchen, es zu bewerten, und selbst divergieren zu ⊥.Was
seq
bedeutet, ist, den ersten Parameter auszuwerten (nicht vollständig, sondern auf "schwache Kopfnormalform" [1], dh auf den obersten Konstruktor) und dann den zweiten Parameter zurückzugeben. Wenn es sich bei dem ersten Parameter zufällig um⊥
eine nicht abschließende Berechnung handelt (dh um eine nicht abschließende Berechnung), führt die Auswertung dazu, dass die Berechnungseq
nicht abgeschlossen wird, und somitseq ⊥ a = ⊥
.[1] Freie Theoreme in Gegenwart von seq - Johann, Voigtländer http://www.iai.uni-bonn.de/~jv/p76-voigtlaender.pdf
quelle
f : forall a . a -> T
(bei derT
es sich um einen anderen Typ handelt)f
können keine Dekonstruktoren auf das erste Argument angewendet werden, da nicht bekannt ist, welche Dekonstruktoren angewendet werden sollen. Wir können keinen "Fall" für Typen machen. Ich habe versucht, die obige Antwort zu verbessern (einschließlich des Zitierens von Informationen zurseq
Bewertung in normaler Kopfform).Samson Abramsky hat sich vor langer Zeit mit diesem Thema befasst und einen Artikel mit dem Titel " The Lazy Lambda Calculus " geschrieben. Wenn Sie also formale Definitionen wünschen, sollten Sie hier nachsehen.
quelle
Beweis, dass λ x. Ω ≠ Ω in ist eines der Ziele, die Abramsky sich für seine Theorie der faulen Lambda-Rechnung setzt (Seite 2 seiner Arbeit) , die bereits von Uday Reddy zitiert wurde) setzt, weil beide in normaler Schwachkopfform vorliegen. Ab Definition 2.7 diskutiert er explizit die eta-Reduktion λ x. M x → M ist nicht allgemein gültig, aber es ist möglich, wenn M in jeder Umgebung endet. Dies bedeutet nicht, dass M eine Gesamtfunktion sein muss - nur, dass die Auswertung von M enden muss (z. B. durch Reduzieren auf ein Lambda).
Ihre Frage scheint von praktischen Bedenken (Leistung) motiviert zu sein. Obwohl der Haskell-Bericht möglicherweise nicht ganz klar ist, bezweifle ich, dass λ x gleichgesetzt wird. ⊥ mit ⊥ würde eine nützliche Implementierung von Haskell ergeben; ob es Haskell '98 implementiert oder nicht, ist umstritten, aber angesichts der Bemerkung ist klar, dass die Autoren beabsichtigten, dass dies der Fall ist.
Schließlich, wie ist es, Elemente für einen beliebigen Eingabetyp zu generieren? (Ich weiß, dass QuickCheck die Arbitrary-Typenklasse dafür definiert, aber Sie dürfen hier keine solchen Einschränkungen hinzufügen.) Dies verletzt die Parametrizität.
Aktualisiert : Ich habe es nicht geschafft, dieses Recht zu codieren (weil ich nicht so fließend in Haskel bin), und um dies zu beheben, sind anscheinend verschachtelte
runST
Regionen erforderlich . Ich habe versucht, mit einer einzelnen Referenzzelle (in der ST-Monade) solche beliebigen Elemente zu speichern, sie später zu lesen und universell verfügbar zu machen. Die Parametrizität beweist, dass dasbreak_parametricity
Folgende nicht definiert werden kann (außer durch Zurückgeben von bottom, z. B. eines Fehlers), während die Elemente wiederhergestellt werden könnten, die die vorgeschlagene Folge erzeugen würde.Ich muss zugeben, dass ich die Formalisierung des hier benötigten Parametrizitätsnachweises ein wenig unklar finde, aber diese informelle Verwendung von Parametrizität ist in Haskell Standard. aber ich habe aus Derek Dreyers Schriften gelernt, dass die nötige Theorie in den letzten Jahren schnell ausgearbeitet wird.
EDITs:
quelle
(\x -> writeSTRef cell (Just x) >> return x)
von zufälligen Eingaben führt kein Schreiben in die Zelle aus. Es werden immer nur die ST-Befehle ausgeführt, die es in die übergebene Sequenz schaffenrunST
. Ebenso wird beim Ausführenmain = (putStrLn "Hello") `seq` (return ())
nichts auf dem Display gedruckt.