Was ist der Unterschied zwischen Pattern Matching und Guards?
Ich bin sehr neu in Haskell und der funktionalen Programmierung im Allgemeinen. Meine Frage ist ziemlich grundlegend. Was ist der Unterschied zwischen Pattern Matching und Guards?
Funktion mit pattern-matching
check :: [a] -> String
check [] = "Empty"
check (x:xs) = "Contains Elements"
Funktion mit Wachen
check_ :: [a] -> String
check_ lst
| length lst < 1 = "Empty"
| otherwise = "Contains elements"
Für mich sieht es aus wie Pattern Matching und Guards sind grundsätzlich die gleichen. Beide auswerten einer Bedingung, und wenn Sie wahr ist, wird ausgeführt der Ausdruck hakte es. Bin ich richtig in meinem Verständnis?
In diesem Beispiel kann ich wahlweise pattern matching oder den guards, um zu demselben Ergebnis gelangen. Aber etwas sagt mir, ich bin etwas zu verpassen wichtig. Können wir immer ersetzen eine mit dem anderen?
Könnte mir jemand Beispiele nennen, wo pattern-matching ist bevorzugt über Wachen und Umgekehrt?
- Es muss nicht direkt deine Frage, aber die erste version der Funktion ist wahrscheinlich besser, weil es effizienter ist und die Arbeit wird für unendliche Listen.
- Pattern-matching wird über die form der Daten, Wachen über den Inhalt.
- Überprüfen Sie die definition von pattern matching in die Sprache Haskell-Report.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eigentlich, sind Sie grundsätzlich ganz anders! Zumindest in Haskell jedenfalls.
Wachen sind sowohl einfacher als auch flexibler: Sie sind im wesentlichen nur spezielle syntax, die sich in einer Reihe von wenn-dann-Ausdrücke. Sie können beliebige Boolesche Ausdrücke in die Wachen, aber Sie tun nichts, Sie konnte nicht mit einem normalen
if
.Muster entspricht noch einige zusätzliche Dinge: Sie sind die einzige Weg, Sie zu dekonstruieren Daten, und Sie binden Bezeichner innerhalb Ihrer Reichweite. Im gleichen Sinne, dass die Wachen sind äquivalent zu
if
Ausdrücke, pattern-matching entsprichtcase
Ausdrücken. Erklärungen (entweder auf der obersten Ebene, oder in etwas wie einlet
Ausdruck) sind auch eine form der pattern-match mit "normalen" Definitionen werden Spiele mit der trivialen Muster, ein einzelner Bezeichner.Muster passt in der Regel auch der wichtigste Weg, Zeug passiert eigentlich in Haskell--versucht Sie zu dekonstruieren-Daten in ein Muster ist eines der wenigen Dinge, die Kräfte der Auswertung.
Durch die Art und Weise, können Sie eigentlich tun, pattern matching in top-level Deklarationen:
Dies ist gelegentlich sinnvoll, für eine Gruppe von verwandten Definitionen.
GHC auch bietet die ViewPatterns Erweiterung, welche vereint; Sie können beliebigen Funktionen in einem verbindlichen Kontext und dann pattern match auf das Ergebnis. Das ist doch nur syntaktischer Zucker für das übliche Zeug, natürlich.
Als für den Tag-zu-Tag-Heft von denen zu verwenden, wobei, hier einige rough guides:
Definitiv mit der Mustererkennung für alles, was abgeglichen werden kann, direkt eine oder zwei Konstruktoren Tiefe, wo Sie nicht wirklich über die zusammengesetzten Daten als ganzes, sondern kümmern sich um die meisten der Struktur. Die
@
syntax können Sie binden die gesamte Struktur einer Variablen, während auch pattern matching auf es, aber zu viel zu tun, dass in einem Muster ist hässlich und unleserlich schnell.Definitiv Wachen, wenn Sie brauchen, um eine Wahl zu treffen, basierend auf einer Eigenschaft, die nicht entsprechen, ordentlich auf ein Muster, z.B. Vergleich von zwei
Int
Werte zu sehen, welche größer ist.Wenn Sie nur ein paar Stücke von Daten aus, die tief im inneren eine große Struktur, besonders, wenn Sie auch brauchen, um die Struktur als ganzes, Wachen und accessor-Funktionen sind in der Regel besser lesbar als manche monströsen Muster voller
@
und_
.Wenn Sie brauchen, um die gleiche Sache für die Werte, dargestellt durch verschiedene Muster, aber mit einem praktischen Prädikat, um Sie zu klassifizieren, mit einem einzigen generischen Muster mit einer Wache ist in der Regel besser lesbar. Beachten Sie, dass wenn eine Gruppe von Wachen ist nicht abschließend, etwas, dass nicht alles die Wachen werden drop-down, um das nächste Muster (falls vorhanden). So können Sie kombinieren ein Allgemeines Muster mit einigen filtern zu fangen Ausnahmefällen, dann tut pattern matching auf alles andere, um details zu erhalten, die Sie interessieren.
Definitiv nicht verwenden, Schutzeinrichtungen für die Dinge, die sein könnte, trivial überprüft mit einem Muster. Überprüfung auf leere Listen ist das klassische Beispiel, verwenden Sie ein Muster entsprechen, für das.
Im Allgemeinen, wenn Sie Zweifel haben, nur stick mit pattern-matching-standardmäßig ist es in der Regel schöner. Wenn ein Muster beginnt sich wirklich hässlich oder unübersichtlich, dann stoppen, um zu betrachten, wie sonst könnten Sie schreiben es. Neben der Verwendung der Schutzvorrichtungen, andere Optionen umfassen das extrahieren Teilausdrücke als separate Funktionen oder setzen Sie
case
Ausdrücke innerhalb der Funktion Körper, um ein wenig Druck von der pattern-matching nach unten auf Sie, und aus dem main-definition.Nicht ganz. Erste pattern-matching kann nicht beurteilen, beliebiger Bedingungen. Es kann nur prüfen, ob ein Wert geschaffen wurde, die einen bestimmten Konstruktor.
Zweiten pattern-matching kann bind-Variablen. So, während das Muster
[]
könnte gleichwertig sein, die Wachenull lst
(nicht mit der Länge, weil das würd nicht entspricht - dazu später noch mehr), das Musterx:xs
sicherlich nicht äquivalent zu der Wachenot (null lst)
weil das Muster bindet die Variablenx
undxs
, die die Wache nicht.Einen Hinweis auf die Verwendung
length
: Mitlength
um zu überprüfen, ob eine Liste leer ist, ist es sehr schlechte Praxis, da die zum berechnen der Länge muss es gehen durch die ganze Liste, dieO(n)
Zeit, während nur die überprüfung, ob die Liste leer ist, dauertO(1)
Zeit mitnull
oder pattern matching. Weiter mit der `Länge einfach nicht auf unendlichen Listen.Für ein, Sie können Boolesche Ausdrücke innerhalb einer Wache.
Zum Beispiel:
Update
Gibt es ein nettes Zitat von Lernen Sie eine Haskell über den Unterschied:
Zusätzlich zu den anderen guten Antworten, ich werde versuchen zu spezifisch über-Wachen: die Wachen sind nur syntaktischer Zucker. Wenn Sie darüber nachdenken, werden Sie oft haben die folgende Struktur in Ihre Programme:
Ist, ob ein Muster passt, es folgt rechts nach einer wenn-dann-sonst Diskriminierung. Eine Wache Falten diese Diskriminierung in den pattern-match-direkt:
(
otherwise
definiert istTrue
in der standard-Bibliothek). Es ist bequemer als eine if-then-else-Kette und manchmal macht es auch der code viel einfacher Variante-Weise, so ist es einfacher zu schreiben, als die if-then-else-Konstruktion.In anderen Worten, es ist Zucker auf der Oberseite von einem anderen Bau in einer Weise, die stark vereinfacht den code in vielen Fällen. Sie werden feststellen, dass es beseitigt eine Menge von if-then-else-Ketten und machen den code lesbarer zu gestalten.
p x
dann eherp(x)
.