Dies ist meine take
version mit foldr
:
Die Ausgabe ist nicht das, was ich erwarte:
%Vor% Ich versuchte dann zu debuggen, indem ich die Länge von y
in sich selbst einfügte und das Ergebnis war:
Ich verstehe nicht, warum die Längen in absteigender Reihenfolge eingefügt werden. Vielleicht etwas Offensichtliches, das ich vermisst habe?
Wenn Sie take
mit foldr
implementieren möchten, müssen Sie das Durchlaufen der Liste von links nach rechts simulieren. Der Punkt besteht darin, die Faltungsfunktion von einem zusätzlichen Argument abhängig zu machen, das die gewünschte Logik codiert und nicht nur vom gefalteten Ende der Liste abhängt.
Hier gibt foldr
eine Funktion zurück, die ein numerisches Argument annimmt und die Liste von links nach rechts durchläuft und dabei die benötigte Menge verwendet. Dies funktioniert auch auf unendlichen Listen aufgrund von Faulheit. Sobald das zusätzliche Argument Null erreicht, wird foldr
kurzgeschlossen und eine leere Liste zurückgeben.
foldr
wendet die Funktion step
beginnend mit den * letzten Elementen ** an. Das heißt,
Die Längen werden in absteigender Reihenfolge "eingefügt", weil :
eine vorbereitende Operation ist. Die längeren Längen werden am Anfang der Liste hinzugefügt.
(Bild aus Ссылка )
*: Der Einfachheit halber gehen wir davon aus, dass jede Operation streng ist, was in OPs step
Implementierung gilt.
Die anderen Antworten machen es viel zu kompliziert, weil sie zu sehr mit der Vorstellung verbunden sind, dass foldr
"von rechts nach links" arbeitet. Es gibt einen Sinn, in dem es tut, aber Haskell ist eine faule Sprache, so dass eine "rechts nach links" -Berechnung, die einen Lazy-Fold-Schritt verwendet, tatsächlich von links nach rechts ausgeführt wird, da das Ergebnis verbraucht wird.
Studiere diesen Code:
%Vor%