2016-01-22 18 views
6

Ich bin neu in OCaml und lese das Real World OCaml (RWO) Buch. Der Mustervergleich wird in Kapitel 3 beschrieben und scheint im Vergleich zu Erlangs (oder Prologs) Mustervergleich schwach zu sein.Warum ist OCamls Mustervergleich schwächer als Erlangs?

Meine Fragen sind:

  1. warum schwächer OCaml der Pattern-Matching?
  2. gibt es irgendwelche Vorteile zu OCamls Art des Musterabgleichs?

Ein konkretes Beispiel:

die folgende Funktion (. Genommen von RWO S. 63) destutters eine Liste

let rec destutter list = 
    match list with 
    | [] -> [] 
    | [hd] -> [hd] 
    | hd :: hd' :: tl -> 
     if hd = hd' then ds1 (hd' :: tl) 
     else hd :: ds1 (hd' :: tl) 
    ;; 

# destutter [1;2;3;3;4;5;5;6];; 
- : int list = [1; 2; 3; 4; 5; 6] 

In Erlang wäre es möglich (und ich denke, bevorzugt) Muster verwenden anstelle der bedingten Anpassung:

destutter([])  -> []; 
destutter([X])  -> [X]; 
destutter([H,H|T]) -> destutter([H|T]); 
destutter([H|T]) -> [H | destutter(T)]. 

der Versuch, diese Art der Sache in OCaml ...

let rec destutter list = 
    match list with 
    | [] -> [] 
    | [hd] -> [hd] 
    | hd :: hd :: tl -> destutter tl (* error *) 
    | hd :: tl -> hd :: destutter tl 
    ;; 

... löst einen Fehler auf der markierten Linie:

Error: Variable hd is bound several times in this matching 

So Erlang/Prolog-Stil Pattern Matching in OCaml funktioniert nicht. Warum? Was sind die Vorteile des OCaml-Ansatzes?

Mit Dank und die besten Wünsche

Ivan

+0

Sehr interessante Frage, ich muss unbedingt mehr über Erlang erfahren! –

Antwort

5

Die Erlang Muster ist mächtiger, weil es gegen etwas zur Laufzeit bestimmt mithalten können. Die OCaml-Muster stimmen mit Dingen überein, die zur Kompilierungszeit festgelegt wurden. Daraus folgt, dass die OCaml-Muster wahrscheinlich schneller gemacht werden können. Ich finde auch, dass OCaml-ähnliche Muster leichter zu verstehen sind.

+1

Danke für deine Antwort! Drei sehr gute Antworten und sehr schwer zu entscheiden, was zu akzeptieren ist. - Sie finden OCaml-ähnliche Muster leichter zu verstehen, weil Sie mit OCaml besser vertraut sind als mit Erlang? Wie kann ich OCaml PMs aus Erlang lieben? –

4

Muster in OCaml sind in einem sehr effizienten Code mit vielen sophisticated optimizations zusammengestellt. Bjarne Stroustrup sogar bragged, dass sie in bestimmten Fällen in C++ etwas Vergleichbares schreiben konnten. Aber im Allgemeinen ist OCaml Pattern Matchin viel schneller. Und es ist charmant, den Montage-Output zu betrachten. Und vielleicht bietet Erlang mehr Flexibilität, aber es wird von einer dynamischen Sprache erwartet. Ansonsten, warum man sie überhaupt benutzt.

Es gibt ein anderes Problem auch. Muster sind strukturell aufeinander abgestimmt. Wenn Sie mit [H,H|T] übereinstimmen möchten, rufen Sie tatsächlich einen Vergleich der ersten beiden Elemente auf. In den meisten Fällen sollte die Vergleichsfunktion von einem Benutzer bereitgestellt werden und ist nicht im Voraus bekannt.

+0

Danke für Ihre Antwort! Drei sehr gute Antworten und sehr schwer zu entscheiden, was zu akzeptieren ist. –

+0

Der Artikel über Pattern-Matching-Optimierung ist faszinierend, danke fürs Schreiben dieser Antwort! –

8

Erstens können Sie immer erfassen die Gleichstellung von Mustervariablen über eine when Klausel in OCaml, z.B .:

let rec destutter = function 
    | []    -> [] 
    | [hd]   -> [hd] 
    | hd :: hd' :: tl 
     when hd = hd' -> destutter (hd :: tl) 
    | hd :: hd' :: tl -> hd :: destutter (hd' :: tl) 

Es gibt einen Trade-off ist hier. Während Erlang ausdrucksstärker ist, ist OCaml-Mustervergleich einfacher (was eine einfachere Sprachdefinition, Compiler usw. bedeutet), und Sie können immer noch tun, was Sie brauchen (auf Kosten des Schreibens von mehr Code).

Beachten Sie, dass Sie zwar ein nichtlineares Muster als lineares Muster mit einer when-Klausel umschreiben können, dies jedoch nicht das primäre Problem ist.Entscheidender ist, dass die Mustererkennung dann eine Vorstellung von Gleichheit für beliebige Typen haben muss, um nichtlineare Muster zu unterstützen. Dies ist kein Problem in Erlang, aber OCaml hat nicht nur bereits = vs == Built-in (strukturelle Gleichheit vs. Identität), aber für jeden gegebenen Typ, kann es nicht die Art der Gleichheit sein, die Sie brauchen (denken Sie Strings und Fall -sensitivity, zum Beispiel). Dann wird die Überprüfung auf Vollständigkeit oder Überlappung nicht trivial. Am Ende ist es fraglich, ob es sinnvoll ist, einen speziellen Fall für eine bestimmte Art von Gleichheit bereitzustellen, wenn man bedenkt, wie viele nützliche Beziehungen zwischen Teilen eines Musters bestehen können. (Ich bemerke, dass nicht-strikte Sprachen zusätzliche Probleme haben.)

Nebenbei, Prolog Mustervergleich ist Vereinheitlichung-basierte und strengere als entweder Erlang oder OCaml (aber auch schwieriger zu implementieren).

+1

Danke für Ihre Antwort! Drei sehr gute Antworten und sehr schwer zu entscheiden, was zu akzeptieren ist. - wenn auch in Erlang Klauseln verfügbar sind (Wächter genannt). Ein ähnliches Beispiel kommt etwas später im RWO-Buch, aber ich werde die Erlang-Stil-PMs vermissen :( –