Frage

Ich habe versucht, den Unterschied zwischen Switch-Anweisungen und Mustererkennung (F #), um ein paar Leute zu erklären, aber ich habe nicht wirklich in der Lage gewesen, es zu erklären well..most die Zeit schauen sie mich an nur und sage "so, warum Sie nicht nur verwenden if..then..else".

Wie würden Sie erklären es ihnen?

EDIT! Vielen Dank an alle für die tollen Antworten, ich wünschte, ich könnte mehr richtigen Antworten markiert.

War es hilfreich?

Lösung

Nachdem wir schon früher eine „jener Leute“, ich weiß nicht, dass es eine prägnante Art und Weise ist zu summieren, warum Pattern-Matching so leckere Güte ist. Es ist erfahrungs.

Als ich gerade im Pattern-Matching geblickt und dachte, dass es eine glorifizierte switch-Anweisung war, glaube ich, dass ich keine Erfahrung Programmierung mit algebraischen Datentypen hatte (Tupeln und diskriminiert Gewerkschaften) und sah nicht ganz dieses Muster Matching war sowohl ein Kontrollkonstrukt und ein bindendes Konstrukt. Nun, da ich habe mit F # Programmierung, habe ich endlich „get it“. Pattern-Matching der Kühle ist aufgrund einer Einmündung von Funktionen in funktionalen Programmiersprachen gefunden, und so ist es nicht trivial für die Außenseiter-looking-in zu schätzen wissen.

Ich habe versucht, einen Aspekt zusammenzufassen, warum Pattern-Matching in der zweiten von einer kurzen zweiteiligen Blog-Serie auf Sprache und API-Design nützlich ist; Besuche Teil eines und Teil zwei .

Andere Tipps

Muster geben Sie eine kleine Sprache, die Struktur der Werte, die Sie anpassen möchten, beschreiben. Die Struktur kann beliebig tief sein, und Sie können Variablen auf Teile des strukturierten Wert binden.

Auf diese Weise können Sie die Dinge extrem kurz und bündig schreiben. Sie können dies mit einem kleinen Beispiel erläutern, wie eine Ableitungsfunktion für eine einfache Art von mathematischen Ausdrücken:

type expr =
    | Int of int
    | Var of string
    | Add of expr * expr
    | Mul of expr * expr;;

let rec d(f, x) =
    match f with
    | Var y when x=y -> Int 1
    | Int _ | Var _ -> Int 0
    | Add(f, g) -> Add(d(f, x), d(g, x))
    | Mul(f, g) -> Add(Mul(f, d(g, x)), Mul(g, d(f, x)));;

Darüber hinaus, da Mustervergleich ein statisches Konstrukt für statischen Typen ist, kann der Compiler (i) sicherzustellen, dass Sie auf alle Fälle abgedeckt (ii) erkennen redundante Zweige, die nie einen beliebigen Wert entsprechen kann (iii) eine sehr effiziente Implementierung (mit springt usw.).

Auszug aus diesem Blog-Artikel :

Pattern Matching hat mehrere Vorteile gegenüber Schalt Anweisungen und Verfahren Dispatch:

  • Muster passt auf Ints wirken kann, Schwimmer, Streicher und andere Arten wie auch Objekte.
  • Muster entsprechen, kann auf mehr handeln verschiedene Werte gleichzeitig: parallel Musteranpassung. Methode Versand und die Schalter werden auf einen einzigen begrenzt Wert, z.B. "This".
  • Muster können verschachtelt werden, so dass Versand über Bäume willkürlichen Tiefe. Verfahren Versand und Schalter sind begrenzt, auf den nicht-verschachtelten Fall.
  • Oder-Muster erlauben Subpattern zu sein geteilt. Methode ermöglicht nur Dispatch teilen, wenn Methoden von Klassen, die eine Basis teilen passieren Klasse. Ansonsten müssen Sie manuell ausklammern die Gemeinsamkeit in eine separate Funktion (die er einen nennen) und dann manuell Anrufe einfügen von allen entsprechenden Stellen zu Ihrem unnötige Funktion.
  • Pattern Matching bietet Redundanz Prüfen, welche Fehler zu erreichen.
  • Verschachtelte und / oder parallel Muster Spiele werden für Sie durch die optimierte F # Compiler. Die OO Äquivalent wird von Hand geschrieben und ständig reoptimiert von Hand während Entwicklung, die unerschwinglich ist mühsam und fehleranfällig, so OO-Code in Produktionsqualität neigt dazu, extrem langsam im Vergleich.
  • Aktive Muster können Sie injizieren benutzerdefinierte Versand Semantik.

Aus der Spitze von meinem Kopf:

  1. Der Compiler kann sagen, wenn Sie nicht alle Möglichkeiten in Ihren Spielen abgedeckt haben
  2. Sie können ein Spiel als eine Zuordnung verwenden
  3. Wenn Sie eine diskriminierte Vereinigung haben, kann jedes Spiel eine andere ‚Art‘

Schalter sind die beiden Vorderräder.

Pattern-Matching ist das ganze Auto.

Tupeln haben "" und Varianten haben Ctor args .. diese sind Konstrukteure, sie schaffen Dinge.

Muster sind Destruktoren, sie reißen sie auseinander.

Sie sind Dual-Konzepte.

diese mit mehr Nachdruck legen: die Vorstellung eines Tupels oder eine Variante kann nicht nur durch den Konstruktor beschrieben werden: der destructor erforderlich ist oder der Wert, der Du unbrauchbar gemacht ist. Es ist diese doppelten Beschreibungen, die einen Wert definieren.

Im Allgemeinen denken wir von Konstrukteuren als Daten und Destruktoren als Kontrollfluss. Variante Destruktoren sind alternative Zweige (einer von vielen), Tupels Destruktoren parallelen Fäden (alle von vielen).

Die Parallelität ist evident in Operationen wie

(f * g) . (h * k) = (f . h * g . k) 

Wenn Sie denken, der Kontrolle durch eine Funktion fließt, bieten Tupeln eine Möglichkeit, eine Berechnung in parallele Threads der Steuerung aufzuteilen.

auf diese Weise betrachtet, Ausdrücke sind Wege Tupeln zu komponieren und Varianten komplizierte Datenstrukturen (denken Sie an eine AST).

machen

Und Muster Einstimmungen gibt Möglichkeiten, die Destruktoren (wieder, denken Sie an eine AST).

zusammen

Muster passen in OCaml, abgesehen davon, dass ausdruck erwähnt wie auf verschiedene Weise, die oben beschrieben wurde, auch einige sehr wichtige statische Garantien geben. Der Compiler wird für Sie beweisen, dass der Fall-Analyse von Ihrem Muster-match-Anweisung ausgeführt ist:

  • Anspruch auf Vollständigkeit (keine Fälle verpasst)
  • Nicht-redundant (keine Fälle, die nie getroffen werden können, weil sie von einem frühen Fall vorweggenommen werden)
  • Sound (keine Muster, die der Datentyp in Frage unmöglich gegeben sind)

Dies ist eine wirklich große Sache. Es ist hilfreich, wenn Sie das Programm zum ersten Mal schreiben, und enorm hilfreich, wenn Ihr Programm entwickelt sich weiter. Richtig eingesetzt, Match-Aussagen erleichtern zuverlässig die Typen im Code zu ändern, da die Typsystem Sie an den gebrochenen Spiel Aussagen Punkte, die sind ein anständiger Indikator, wo Sie Code haben, der behoben werden muss.

If-Else (oder Switch) Aussagen über wählen verschiedene Möglichkeiten, einen Wert (Eingang) in Abhängigkeit von Eigenschaften des Wertes bei der Hand zu verarbeiten.

Pattern Matching ist zu definieren, wie ein Wert zu verarbeiten aufgrund seiner Struktur (Beachten Sie auch, dass Einzelfall Muster paßt Sinn machen).

So Musterabgleich wird mehr über Werte als Entscheidungen zu treffen dekonstruiert, macht dies sie einen sehr bequemer Mechanismus für die Definition (rekursiv) Funktionen auf induktive Strukturen (rekursive Vereinigungstypen), was erklärt, warum sie so reichlich in Sprachen wie Ocaml verwendet usw. .

PS: Sie können das Muster-Spiel kennen und If-Else "Muster" von ihrem Ad-hoc-Einsatz in Mathematik;

"wenn x hat die Eigenschaft A dann y sonst z" (If-Else)

"einige Begriffe in p1..pn wo .... die Primzerlegung von x .." ((Einzelfall) Mustervergleich)

Vielleicht könnten Sie eine Analogie mit Streichern und regulären Ausdrücken ziehen? Sie beschreiben was Sie suchen, und lassen Sie den Compiler Figur aus wie für sich. Es macht Ihren Code wesentlich einfacher und übersichtlicher.

Als Nebenwirkung: Ich finde, dass das nützlichste, was über Mustervergleich ist, dass es gute Gewohnheiten fördert. Ich beschäftige mich mit den Eckfällen erste , und es ist leicht zu überprüfen, dass ich jeden Fall behandelt haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top