fold_tree in OCaml

7

Wie Sie vielleicht wissen, gibt es in OCaml Funktionen wie fold_left, fold_right, filter etc.

Auf meinem Kurs in funktionaler Programmierung wurde Funktion namens fold_tree eingeführt, die etwas wie fold_left / right, nicht auf Listen, sondern auf (binären) Bäumen ist. Es sieht so aus:

%Vor%

Wo Baum definiert ist als:

%Vor%

OK, hier ist meine Frage: Wie funktioniert die Funktion falt_tree? Können Sie mir einige Beispiele geben und in menschlicher Sprache erklären?

    
equrts 15.11.2010, 22:32
quelle

5 Antworten

8

Hier ist ein Stilvorschlag, setzen Sie die Balken am Anfang der Zeile. Es macht deutlicher, wo ein Fall beginnt. Aus Konsistenzgründen ist der erste Balken optional, wird aber empfohlen.

%Vor%

Wie es funktioniert, betrachten Sie den folgenden Baum:

%Vor%

Mit dem Typ int tree .

Visuell sieht t folgendermaßen aus:

%Vor%

Und wenn wir fold_tree aufrufen, brauchen wir eine Funktion, um die Werte zu kombinieren. Basierend auf der Verwendung im Fall Node benötigt f 3 Argumente, alle vom selben Baumtyp und gibt dasselbe zurück. Wir machen das:

%Vor%

Es würde helfen zu verstehen, was in jedem Fall passiert. Für Leaf wird a zurückgegeben. Für jede Node kombiniert sie den gespeicherten Wert und das Ergebnis der Faltung der linken und rechten Teilbäume. In diesem Fall fügen wir nur die Zahlen hinzu, bei denen jedes Blatt als eins zählt. Das Ergebnis der Faltung dieses Baumes ist 10 .

    
Jeff Mercado 15.11.2010, 23:10
quelle
5

Nehmen wir einen Beispielbaum.

%Vor%

Die allgemeine Definition einer falten Operation besteht darin, dass Sie Konstruktoren durch Funktionen überall in ersetzen der Baum.

%Vor%

node ist eine Funktion, die ein etwas aus einem linken etwas , einem Element und einem rechten Etwas , genau wie% co_de, konstruiert % ist ein Konstruktor, der einen Baum aus einem linken Teilbaum, einem Knoteninhalt und einem rechten Teilbaum konstruiert. Node ist eine Konstante, die dem Konstantenkonstruktor leaf entspricht.

%Vor%

Beachten Sie, dass die Typen der Funktionen mit denen der Typdefinition übereinstimmen, außer dass die Typdefinition, wenn die Typdefinition die Erstellung eines Leaf beschreibt, die Erstellung eines beliebigen 'a tree beschreibt.

Operationen, die der allgemeinen Faltung sehr ähnlich sind, werden immer noch Falte genannt. In Listen beispielsweise ist 'b die allgemeine Falte gemäß der obigen Definition; List.fold_right ist eine Variation, die die Funktion anders herum anwendet ( List.fold_left ist gleichbedeutend mit reverse + fold_left + reverse, obwohl es klarer und effizienter ist).

Ihre eigene fold_right ist eine einfache Variante dieser allgemeinen Faltung, bei der die Knotenfunktion ihre Argumente in einer anderen Reihenfolge als der Konstruktor verwendet:

%Vor%     
Gilles 16.11.2010 00:39
quelle
4

Hier ist eine Möglichkeit, über fold_right auf Listen nachzudenken: Eine Liste ist zum Beispiel

%Vor%

und Sie interpretieren die Liste mit einer neuen binären Operation anstelle von :: (und einer neuen Konstante anstelle von []) neu.

%Vor%

Wenn Sie Ihrer Liste absolut nichts hinzufügen wollten, könnten Sie die Funktion cons als Funktion und die leere Liste als neutrales Element übergeben. In gewisser Hinsicht ist fold_right sehr allgemein gehalten: Sie können sogar gar keine Informationen verlieren.

Die fold_tree in Ihrer Frage ist die gleiche Idee für den Datentyp von Bäumen. Wenn Sie Ihren Baum neu interpretieren möchten, übergeben Sie ihm eine neue Funktion für Knoten, die anstelle des Konstruktors Node angewendet werden. Wenn Sie einen identischen Baum erhalten möchten, können Sie ihn mit Leaf als neutral und (fun x l r -> Node (l, x, r)) als Funktion anwenden. Ähnlich wie fold_left für Listen ist diese Beispielanwendung nicht sehr interessant, aber es bedeutet, dass fold_left eine sehr allgemeine Transformation ist (der Fachausdruck ist Morphismus ).

Sie können die Elemente des Baums auch mit der Funktion (fun x l r -> x + l + r) zum Beispiel summieren.

    
Pascal Cuoq 15.11.2010 23:12
quelle
3

Sie könnten gerne lesen

Ссылка

Ссылка

welche in F # sind, aber F # ist sehr ähnlich zu OCaml.

    
Brian 16.11.2010 02:01
quelle
3

Es scheint, dass f eine Reduktionsfunktion mit drei Parametern ist, a ist das neutrale Element unserer Reduktion und t ist die Wurzel, also:

binär wie (ich erinnere mich nicht sehr gut an die Syntax von Variant-Typen, bitte seien Sie hier).

%Vor%

Wenn Sie alle Knoten summieren möchten, wird die Funktion wie folgt aufgerufen:

%Vor%

und wir erhalten t als Knoten, also haben wir:

%Vor%

Wenn wir es ein wenig erweitern, erhalten wir:

%Vor%

und noch einmal, wir passen die Blätter zusammen:

%Vor%

um endlich zu bekommen:

%Vor%

Ich hoffe, es hilft.

    
fortran 15.11.2010 22:58
quelle