2017-12-28 13 views
1

Ich lese die Frage About `let 5 = 10` und ich benutze keine hier, in meinem Beispiel schreibe ich den Code in eine Datei und die Ausführung, so dass meine Frage noch nicht beantwortet ist, keine davon beantwortet sind nützlich für mich.Verständnis Binding und Mustererkennung

Ich habe heute eine ähnliche Frage über [seltene Pattern Matching] [1] gestellt, ein Freund von uns lehrt uns die Grundlagen der funktionalen Programmierung in Haskell, und er fing an, die seltenste Sache zu schreiben, die ich je gesehen habe:

Er begann mit etwas nicht so erstaunlich, aber ziemlich cool:

(x,y) = (10,20) 
(z:zs) = 0 : [1..] 

und zeigt im Vorspiel:

prelude> x 
10 
prelude> z 
0 
prelude> takeN 3 zs 
[1,2,3] 

so weit, so gut ... ich nicht k Jetzt könnten Sie die Werte so binden

(x,y) = (10,20) 
(z:zs) = 0 : [1..] 
True = False -- HERE 

Was !? Jeder in der Klasse Gedanken, ok, wird etwas schief gehen, aber nicht einmal der Code kompiliert, dann läuft es:

prelude> x 
10 
prelude> 4 
4 
prelude> True 
True 
+4

Markieren Sie die Unterschiede, wenn Sie eine Frage erneut stellen, die zuvor als Duplikat geschlossen wurde. – leftaroundabout

+0

Sicher werde ich danke für den Rat –

+1

Was genau ist die Frage –

Antwort

3

Sowohl where und let einführen definieren Gleichungen faul Muster.

In jedem Modul sind alle Definitionen auf oberster Ebene unter where.

module Main where 
     -- ^^^^^ 

x, y :: Int 
(x, y) = undefined 

main :: IO() 
main = putStrLn "hello!" 

Das obige Programm wird wie gewünscht "Hallo" drucken. Das Muster, das gegen (x, y) zusammenpassend ist, würde divergieren, wenn es streng war, aber da es faul ist, tut es nicht - der undefined Ausdruck wird nie ausgewertet.

Definitionen in GHCi eingegeben sind auch unter einer impliziten let.

Nachdem dies bekannt ist, ist das in der Frage erwähnte Problem genau das in der let 5 = 10 Frage.

1

In Haskell macht eine "Bindung" Mustererkennung. Es gibt genau zwei Arten von Pattern-Matching-Binding in Haskell: Sie können entweder P = x schreiben, wobei P ein Muster ist, oder Sie können v1 p1 p2 ... pn = x schreiben, wobei jedes pi ein Muster ist. Dies definiert (Teil von) eine Funktion v1. Was ist ein Muster? Ein Muster ist entweder eine Variable v, die bewirkt, dass v an die Übereinstimmung gebunden wird, wenn die Übereinstimmung erfolgreich ist. Oder ein Muster kann eine Konstante wie 7 sein, bei der, wenn die Anpassung abgeschlossen ist, es nur dann erfolgreich ist, wenn das übereinstimmende Ding gleich der Konstanten ist. Oder ein Muster kann eine Variante eines Datentyps sein: Wenn Foo eine Variante (Konstruktor) für den Typ Bar ist, die n Parameter verwendet, dann Foo p1 p2 ... pn, wobei die pi Muster sind, ist ein Muster, das ein Objekt vom Typ Bar betrachtet und erfolgreich übereinstimmt wenn es von der Foo Variante ist und jeder der pi erfolgreich übereinstimmt.

Da Haskell träge ist, besteht die einzige Möglichkeit, den Musterabgleich zu erzwingen, darin, eine Variable zu verwenden, die durch Mustervergleiche gebunden ist.So kann man die Bindung von x in let (x,5)=(6,6) unter Verwendung x erzwingen, und dies verursacht einen Übereinstimmungsfehler. Wenn eine Variante keine Parameter hat, gibt es keine Möglichkeit, den Abgleich zu erzwingen, so dass die Übereinstimmung nicht fehlschlagen kann. So würde fehlschlagen, wenn Sie jemals die Übereinstimmung zu passieren, aber da es keine Möglichkeit gibt, die Übereinstimmung zu erhalten, gibt es keinen Fehler. Beachten Sie, dass Sie True nicht erneut binden, sondern es als Muster ohne Argumente verwenden.