Rekursion über einen Swift Slicable

8

Ich fühle, dass ich etwas Offensichtliches vermissen muss. Eine Liste in den Kopf und Schwanz zu zerlegen und dann über den Schwanz zu rekursiv ist eine Standard-Funktionsprogrammierungstechnik, aber ich habe Schwierigkeiten, dies für Sliceable -Typen in Swift zu tun.

Ich habe eine rekursive Funktion, die diesem Muster folgt:

%Vor%

Offensichtlich macht der echte Code viel mehr als jede Zahl zur nächsten hinzuzufügen.

Beachten Sie den Aufruf von Array(dropFirst(seq)) . Die Konvertierung in ein Array ist erforderlich, da dropFirst tatsächlich ein ArraySlice zurückgibt und ein ArraySlice kein Sliceable ist, also kann ich es nicht an meine Funktion übergeben.

Ich bin mir nicht sicher, welche Art von Optimierung der Compiler hier kann, aber es scheint mir, dass das Erstellen eines neuen Arrays aus einem SubSlice unnötig nicht optimal ist. Gibt es dafür eine Lösung?

Außerdem würde ich wirklich gerne eine Version dieser Funktion erstellen, die beliebig Sliceable type:

annehmen kann %Vor%

Dieses Mal habe ich keine Lösung für die Tatsache, dass ich ein SubSlice habe. Wie kann ich mein Ziel erreichen?

    
tarmes 18.06.2015, 12:17
quelle

3 Antworten

4

Es stellt sich heraus, dass eine generische Lösung ist. Sie müssen diese generischen Anforderungen hinzufügen:

%Vor%

Für die gestellte Frage ergibt sich:

%Vor%

Hier ist eine nützliche generische Reduzierung für jedes Sliceable:

%Vor%

Ich kann das nicht akzeptieren, die Lösung wurde in den Apple Development Forums veröffentlicht. p>

Es ist eine Schande, dass die generischen Anforderungen für solch eine grundlegende Operation so wichtig sind - es ist kaum intuitiv! Aber ich bin froh, eine Lösung zu haben ...

    
tarmes 18.06.2015, 14:17
quelle
3

Eigentlich ArraySlice ist Sliceable , also können Sie sich darauf freuen ArraySlice<Int> :

%Vor%

mit einer Wrapper-Funktion, die nur einmal auf der obersten Ebene aufgerufen wird:

%Vor%

Ich habe keine Lösung für Ihr zweites allgemeines Problem. Die API-Dokumentation für Sliceable gibt an, dass SubSlice sein sollte Sliceable selbst (was für alle bekannten Sliceable gilt Arten).

Ich habe daher das Gefühl, dass es möglich sein sollte, indem man anfragt dass T.SubSlice selbst mit dem identischen SubSlice schnittbar ist Typ, jedoch kompiliert dies nicht:

%Vor%

Der Compiler akzeptiert, dass dropFirst(list) in T.SubSlice umgewandelt werden kann, aber weigert sich, recurseSeq() auf diesen Wert aufzurufen, was ich nicht tue verstehe.

Alternativ können Sie auch ein GeneratorType :

aufrufen %Vor%

mit einem Wrapper, der ein SequenceType akzeptiert:

%Vor%

Arrays und Array-Slices stimmen alle mit SequenceType überein arbeite in allen deinen Fällen.

    
Martin R 18.06.2015 13:02
quelle
0

Das Erstellen eines Arrays in jeder Iteration scheint keine gute Idee zu sein. Ich weiß nicht, ob der Compiler es irgendwie optimiert, aber Sie könnten wahrscheinlich eine andere Lösung finden.

In diesem Fall könnten Sie z. B. de Rekursion löschen und stattdessen eine for -Schleife verwenden, die das Array an Ort und Stelle ändert.

%Vor%     
Marcos Crispino 18.06.2015 12:48
quelle

Tags und Links