2 Stimmen

OCaml: Das Durchlaufen einer Liste und Überspringen von Elementen, falls der falsche Konstruktor verwendet wird

Dies mag seltsam erscheinen, und Sie sind herzlich eingeladen, einen besseren Weg vorzuschlagen, um es zu tun.

Hier ist mein Ziel:

Ich möchte jedes Element einer in eine Funktion übergebenen Liste durchlaufen. Wenn es vom Konstruktor Y ist, möchte ich eine bestimmte Funktion aufrufen. Wenn es vom Konstruktor Z ist, möchte ich es überspringen.

Wenn es eine Möglichkeit gibt, dies in einer if-Anweisung zu überprüfen, scheint das der richtige Weg zu sein, da ich kein else schreiben muss. Allerdings weiß ich nur, wie ich dies in einer Übereinstimmung überprüfen kann.

Zum Beispiel:

let meineFunktion liste =
List.iter (fun x -> match x with
           | Y y -> andereFunktion y
          ) liste;;

Jetzt erhalte ich eine Warnung, dass Z nicht behandelt werden kann. Also könnte ich etwas wie folgt hinzufügen...

let meineFunktion liste =
List.iter (fun x -> match x with
           | Y y -> andereFunktion y
           | Z z -> (*überspringen*)
          ) liste;;

Natürlich kann ich die Übereinstimmung mit Z nicht einfach leer lassen....

Wie kann ich das erreichen, was ich versuche zu tun?

6voto

Lambdageek Punkte 12456

Geben Sie einfach die Einheit zurück (dh ()) im Z Fall.

Sind Sie sicher, dass Sie List.iter verwenden möchten. Es wird hauptsächlich verwendet, um eine Funktion aufgrund ihrer Nebenwirkung anzuwenden.

Ein eher idiomatischer Ansatz in funktionalen Programmen besteht darin, die Liste mit List.filter zu filtern und dann eine Transformation auf alle verbleibenden Elemente mit List.map anzuwenden.

1voto

sashang Punkte 10936

Sie könnten List.filter verwenden, um die Liste basierend auf der Bedingung zu filtern, und dann List.iter auf der gefilterten Liste verwenden.

Sehen Sie hier die Dokumentation für weitere Informationen über die Methoden im Listenmodul. http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html

Ich habe momentan keinen Zugang zum OCaml-Compiler, aber der Code würde ungefähr so aussehen:

List.iter (fun x -> ....) (List.filter (fun x -> ...) mylist)

1voto

Jeffrey Scofield Punkte 63703

Die Antwort von Lambdageek für List.iter ist richtig. Du musst nur () als dein Ergebnis verwenden in jedem Fall, wo du nichts zu tun hast. Alle verschiedenen Fälle deines match-Ausdrucks sollten () zurückgeben, wenn du eine Iteration durchführst. Darum geht es bei List.iter.

Jeder andere macht sich (zu Recht, meiner Meinung nach) Sorgen, dass du vielleicht wirklich nicht List.iter verwenden möchtest. Es könnte das Erste sein, was dir einfällt, wenn du aus anderen (imperativen) Sprachen kommst, aber Iteration per se wird bei der funktionalen Programmierung überhaupt nicht so häufig verwendet. Wenn du OCaml in einem Kurs lernst, ist es sogar noch unwahrscheinlicher, dass du List.iter verwenden möchtest. Ein Kurs über OCaml würde definitiv mit den funktionalen Teilen beginnen. Um funktional zu denken, möchtest du darüber nachdenken, Werte von einer Form in eine andere zu transformieren (d.h. Funktionen auf sie anzuwenden).

Angenommen, du möchtest List.filter verwenden. Dann wirst du, wie du sagst, einen match-Ausdruck durchführen, aber anstelle von () in allen verschiedenen Fällen möchtest du in jedem Fall ein Boolean (true oder false) zurückgeben. Wenn du true zurückgibst, wird der Wert in die resultierende Liste aufgenommen. Wenn du false zurückgibst, wird der Wert nicht in die resultierende Liste aufgenommen. Auch hier geht es bei List.filter darum. Hier ist etwas Code, der eine neue Liste zurückgibt, die nur die Elemente einer gegebenen Liste enthält, die einen Z-Konstruktor haben.

let myFunc list =
    List.filter
        (fun x -> match x with Z _ -> true | _ -> false)
        list

Ich bin mir nicht sicher, ob das hilft, aber ich denke, was ich sagen möchte, ist, dass match zu verwenden nicht schwierig ist. Du musst einfach jeden Fall abdecken. Das ist gut, du möchtest, dass dein Code in jedem Fall funktioniert!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X