Looping in der funktionalen Programmierung ist nicht mit Steueranweisungen getan wie for
und while
, es gemacht mit expliziten Aufrufen von Funktionen wie map
, fold
oder Rekursion - all das beinhaltet den innere Schleife Anruf in einer anderen Funktion . Wenn der Schleifencode Variablen außerhalb der Schleife mutiert, manipuliert diese innere Schleifenfunktion Variablen außerhalb ihres Gültigkeitsbereichs und wäre daher unrein . Die gesamte äußere Funktion ist also rein, die Schleife jedoch nicht. Bei Schleifenkonstrukten in der funktionalen Programmierung müssen Sie den Status explizit angeben. Das Übersetzen Ihres Codes in etwas mit funktionalen Programmierschleifenwerkzeugen zeigt die Unreinheit:
int as_int(char *str)
{
int acc = 0; /* accumulate the partial result */
map(takeWhile(isdigit, str), void function(char *chr) {
acc = acc * 10 + (chr - '0');
});
return acc;
}
(Hinweis - Diese Syntax ist ungefähr, um die allgemeine Vorstellung zu vermitteln.)
Dieser Code verwendet eine innere Funktion für den Schleifenkörper, die die Variable mutieren muss acc
, die außerhalb ihres Gültigkeitsbereichs liegt. Dies ist unrein - die Funktion der inneren Schleife hängt vom Kontext der äußeren Schleife ab . Wenn Sie sie mehrmals mit demselben Zeichen aufrufen, hat dies Nebenwirkungen, und die Reihenfolge, in der Sie sie in der Reihenfolge der Zeichen aufrufen, ist von Bedeutung. Um dies in der funktionalen Programmierung zu einer reinen Funktion zu machen, müssten Sie diese Abhängigkeit vom Zustand, der zwischen Schleifeniterationen übergeben wird, explizit machen mit fold
:
int as_int(char *str)
{
return fold(takeWhile(isdigit, str), 0, int function(char *chr, int acc) {
return acc * 10 + (chr - '0');
});
}
fold
verwendet eine Funktion von zwei Argumenten für den inneren Schleifenkörper: Das erste Argument ist ein Element in der Sequenz, die fold
eine Schleife durchläuft, während das zweite ein Wert ist, den der innere Schleifenkörper verwendet, um Teilergebnisse aufzubauen. Für die erste Schleifeniteration acc
ist 0, für die zweite acc
ist alles , was der erste Aufruf der inneren Schleifenfunktion zurückgegeben hat, für die dritte ist es, was auch immer die zweite innere Schleife zurückgegeben hat, und die letzte Schleife gibt das Ergebnis des gesamten fold
Ausdrucks zurück.
Beachten Sie, dass dies aus Sicht des restlichen Programms kein wirkliches Problem mit Ihrem Code darstellt - beide Definitionen von as_int
sind rein. Der Unterschied besteht darin, dass Sie den Code der inneren Schleife zu einer reinen Funktion machen. Sie können die zahlreichen Tools nutzen, die die funktionale Programmierung bietet, um die Schleife in etwas Deklarativeres zu zerlegen (z. B. mithilfe von takeWhile, fold, filter, map usw. usw.).