Ein Beispiel aus der Praxis, wenn Mustervergleich besser ist als ein Case-Ausdruck in Haskell?

8

Ich war also mit dem Real World Haskell Buch beschäftigt und habe die lastButOne Übung gemacht. Ich habe zwei Lösungen gefunden, eine mit Mustererkennung

%Vor%

Und einer, der einen Case-Ausdruck verwendet

%Vor%

Was ich herausfinden wollte, ist, wann Pattern Matching den Case-Ausdrücken vorgezogen wird und umgekehrt . Dieses Beispiel war nicht gut genug für mich, weil es scheint, dass, während beide Funktionen wie beabsichtigt funktionieren, es mich nicht dazu brachte, eine Implementierung gegenüber der anderen zu wählen. Also scheint die Wahl auf den ersten Blick "bevorzugt" zu sein?

Gibt es also gute Fälle mit Quellcode, entweder in haskells eigener Quelle oder GitHub oder irgendwo anders, wo man sehen kann, wann eine Methode bevorzugt wird oder nicht?

    
Shiraaz.M 03.12.2015, 19:58
quelle

4 Antworten

15

Zuerst eine kurze Terminologieumleitung: Ich würde beide als "Mustervergleich" bezeichnen. Ich bin mir nicht sicher, ob es einen guten Ausdruck dafür gibt, Pattern-Matching-über-Case und Pattern-Matching-via-Multiple-Definition zu unterscheiden.

Die technische Unterscheidung zwischen den beiden ist in der Tat ziemlich leicht. Sie können dies selbst überprüfen, indem Sie GHC bitten, den Kern, den es für die beiden Funktionen generiert, mit dem -ddump-simpl -Flag zu löschen. Ich habe das auf einigen verschiedenen Optimierungsebenen versucht, und in allen Fällen waren die einzigen Unterschiede im Kern die Benennung. (Übrigens, wenn irgendjemand ein gutes "semantisches Diff" Programm für Core kennt - das zumindest Alpha-Äquivalenz kennt - bin ich sehr daran interessiert, davon zu hören!)

Es gibt jedoch ein paar kleine Fehler, auf die man achten sollte. Sie könnten sich fragen, ob das Folgende auch gleichwertig ist:

%Vor%

In diesem Fall lautet die Antwort ja. Aber bedenke diesen ähnlich aussehenden:

%Vor%

Plötzlich ist dies eine typenklassenpolymorphe CAF, und auf alten GHCs löst dies die Monomorphie-Beschränkung aus und verursacht einen Fehler, während die oberflächlich identische Version mit einem expliziten Argument nicht:

%Vor%

Der andere kleine Unterschied (den ich vergessen habe - danke an Thomas DuBuisson , dass er mich erinnert hat ) ist im Umgang mit Where-Klauseln. Da where-Klauseln an Bindungsstellen angehängt sind, können sie nicht über mehrere Gleichungen verteilt werden, sondern können über mehrere Fälle verteilt werden. Zum Beispiel:

%Vor%

Man könnte denken, dass das bedeutet, dass man etwas mit Gleichungen machen kann, die man mit Case-Ausdrücken nicht machen kann, nämlich unterschiedliche Bedeutungen für den gleichen Namen in den zwei Gleichungen, wie folgt:

%Vor%

Da die Muster von case -Ausdrücke jedoch Bindungsstellen sind, kann dies auch in case -Ausdrücken emuliert werden:

%Vor%

Ob die where -Klausel an das case -Muster oder an die Gleichung angehängt wird, hängt natürlich von der Einrückung ab.

    
Daniel Wagner 03.12.2015, 20:48
quelle
4

Wenn ich mich richtig erinnere, werden beide diese "entzuckerten" in den gleichen Kerncode in ghc, so ist die Wahl rein stilistisch. Persönlich würde ich für den ersten gehen. Wie jemand sagte, ist es kürzer, und was Sie als "Mustervergleich" bezeichnen, soll auf diese Weise verwendet werden. (Tatsächlich ist die zweite Version auch Mustererkennung, nur mit einer anderen Syntax dafür).

    
Paul Johnson 03.12.2015 20:39
quelle
1

Es ist eine stilistische Vorliebe. Manche Leute argumentieren manchmal, dass die eine oder andere Entscheidung gewisse Codeänderungen weniger anstrengend macht, aber ich finde im Allgemeinen, dass solche Argumente, auch wenn sie korrekt sind, nicht wirklich zu einer großen Verbesserung führen. Mach so, wie du willst.

Eine Perspektive, die es wert ist, hier einzubringen, ist Hudak, Hughes, Peyton Jones und Wadlers Artikel " Eine Geschichte von Haskell: Faulheit mit der Klasse ". Abschnitt 4.4 befasst sich mit diesem Thema. Die Kurzgeschichte: Haskell unterstützt beides, weil sich die Designer nicht untereinander einigen konnten. Ja, es ist wieder eine stilistische Vorliebe.

    
Luis Casillas 03.12.2015 22:01
quelle
0

Wenn Sie auf mehr als einen -Ausdruck abgestimmt haben, sehen case -Ausdrücke attraktiver aus.

%Vor%

kann lästiger schreiben als

%Vor%

Noch wichtiger ist, dass ich festgestellt habe, dass bei der Verwendung von GADTs der "Deklarationsstil" keine Beweise von links nach rechts ausdehnt, wie ich es erwarten würde. Es könnte einen Trick geben, den ich nicht ausgearbeitet habe, aber ich muss case -Ausdrücke schachteln, um falsche unvollständige Musterwarnungen zu vermeiden.

    
dfeuer 04.12.2015 05:07
quelle