Hinzufügen zu einer Zeichenkette in OCaml

8

Ich habe versucht, herauszufinden, was ich für eine ziemlich einfache Aufgabe halte, nämlich Einträge zu einer Karte von Strings in OCaml innerhalb einer Funktion hinzuzufügen. Die relevanten Elemente sind unten:

%Vor%

Ich erhalte immer noch die kryptische "Syntax Error" -Nachricht, aber ich muss noch eine Lösung finden, nachdem ich den Code auf nichts reduziert habe. Ich kann die String Map mit einem einzigen Befehl ergänzen, aber wenn ich let m = StringMap.add hd 1 m innerhalb der Funktion ausführen möchte, kann sie nicht ausgeführt werden. Ich bin sicher, das ist ein einfaches Problem, aber kann jemand bitte helfen? Danke.

    
duanemat 07.10.2010, 03:46
quelle

2 Antworten

15

Es scheint ein paar Probleme mit Ihrem Code zu geben. Aber zuerst, hier ist ein Beispiel, wie man das macht, was man versucht zu tun:

%Vor%

Einige Kommentare zum ursprünglichen Code:

  • doppelte Semikolons werden verwendet, um der REPL-Schleife mitzuteilen, dass sie Ihren Code konsumieren soll. Sie sollten sie vermeiden, wenn Sie sie nicht benutzen.
  • einzelne Semikolons werden verwendet, um imperative Ausdrücke, z. nach einer Aufgabe. Hier haben Sie einen Let-Ausdruck, der die Syntax "let & lt; .. & gt; in & lt; .. & gt;" hat, also verwenden Sie ein Semikolon, nachdem es falsch ist. ("let a = ..." ohne "in" ist ein Toplevel-Konstrukt und nicht etwas, das man lokal verwenden kann).
  • StringMap (und die meisten anderen Strukturen in ocaml) sind funktional, nicht zwingend. Sie können das von Ihnen in der ersten Zeile deklarierte 'm' nicht mutieren. Sie müssen die Struktur erstellen und schließlich die vollständig aufgebaute Struktur am Ende der Schleife zurückgeben.
Sami 07.10.2010, 04:20
quelle
10

Ihre Quelle der Verwirrung ist, dass Sie die Bedeutung des Konstrukts let falsch verstanden haben. Es ändert kein Objekt: es ist keine Zuweisungsanweisung (. Das let -Konstrukt gibt einen Namen für einen Wert . Die Syntax des let Konstrukts ist < br> let Name = Wert in Ausdruck
Dies bewirkt, dass name in Ausdruck auf Wert verweist. Der Wert wird einmal berechnet, bevor der Name an ihn gebunden wird. Der Geltungsbereich von name ist expression , sodass Sie nicht auf value außerhalb von expression verweisen können Wert, auf der anderen Seite lebt weiter, bis Müll gesammelt).

Das Top-Level let -Konstrukt ist ähnlich dem in Ausdrücken, hat aber nicht den in Ausdruck -Teil. Der Geltungsbereich des Namens ist der Rest des Programms (es ist, als ob es ein in -Teil mit allem darunter gab, zumindest bis zu Modulen).

Sie versuchen, die oberste Ebene m zu ändern, aber das ist nicht let 's Aufgabe: Sie würden dafür eine Zuweisung benötigen. Ocaml hat einen Zuweisungsoperator, := , der einer vorhandenen Referenz zuweist. Eine Referenz ist ein Objekt, das geändert werden kann. In Ocaml ist dies nicht automatisch möglich: Im Gegensatz zu Sprachen wie C, Java und Lisp verwendet Ocaml keine einzige Sprachfunktion, um Werte zu benennen und modifizierbaren Speicher zu erstellen. Die Funktion ref erstellt ein modifizierbares Objekt. Sie weisen es mit := zu und verwenden den Operator ! , um seinen Wert zu erhalten:

%Vor%

Dies ist jedoch nicht sehr gut Ocaml-Stil. Ocaml unterstützt diesen imperativen Stil, aber Sie sollten ihn vermeiden, weil imperative Programmierung fehleranfälliger ist als die funktionale Programmierung. Der funktionale Stil erstellt einen neuen Wert, wenn Sie ein Objekt ändern möchten. Beachten Sie, dass Karten, die mit dem Modul Map erstellt wurden, diesen Stil unterstützen: add gibt ein neues Objekt zurück, das neben dem alten Objekt existiert (d. H. Es handelt sich um eine persistente Datenstruktur ). Um zu einem funktionalen Stil zu wechseln, müssen Sie die Schnittstelle der Funktion count ändern. Es ist etwas, was Sie trotzdem tun möchten, um die Funktion count auf verschiedenen Maps verwenden zu können, indem Sie die Map als Argument übergeben. Ich verweise Sie auf Samis Antwort zum Beispiel Code in guter Ocaml-Stil.

    
Gilles 07.10.2010 07:32
quelle

Tags und Links