2014-05-23 6 views
5

In Control.Lens.Traversal die beside Funktion durchläuft beide Teile eines Bitraversable. Das Beispiel istWie kann ich verschiedene Teile der Datenstruktur nacheinander durchlaufen?

>>> ("hello",["world","!!!"])^..beside id traverse 
["hello","world","!!!"] 

Kann ich eine explizitere Version von beside schreiben (nennen wir es bothParts), dass anstelle einer Bitraversable Einschränkung dauert zwei Traversal s? Ich stelle mir vor, dass es so verwendet wird:

>>> ("hello",["world","!!!"])^..bothParts _1 _2 id traverse 
["hello","world","!!!"] 

Gibt es das schon? Ist das zu unsicher, um vernünftig benutzt zu werden? Vielen Dank!

Edit:

Oder vielleicht so etwas wie:

>>> ("hello",["world","!!!"])^..bothParts _1 (_2.traverse) 
["hello","world","!!!"] 
+2

Ich denke, dass 'bothParts l1 l2' nicht immer ein gültiges' Traversal' sein wird. Betrachte 'bothParts _1 _1' (oder jeden anderen Fall, wenn' l1' und 'l2' sich überlappen). – fizruk

Antwort

2

Der Kombinator von Ihnen gewünschte soll gleichzeitig 2 Traversal s verwenden. Aber diese Art von Kombinator bricht Traversal Gesetze im Allgemeinen, insbesondere das Gesetz "keine Verdoppelung": ein Traversal sollte jedes Element nur einmal durchlaufen.

Hier ist ein Beispiel dafür, was Sie wollen wahrscheinlich nicht:

>>> (1, 2) ^.. bothParts _1 _1 
[1, 1]  

genauer zu sein, würde Ich mag Traversal documentation from lens package zitieren:

Die Gesetze für eine Traversal t ergeben sich aus den Gesetze für Traversable wie in "The Essence of the Iterator Pattern" angegeben.

t pure ≡ pure 
fmap (t f) . t g ≡ getCompose . t (Compose . fmap f . g) 

Eine Folge dieser Anforderung ist, dass ein Traversal Bedarf die gleiche Anzahl von Elementen als Kandidat für die nachfolgenden Traversal, dass es mit begann zu verlassen. Ein weiterer Beweis für die Stärke dieser Gesetze ist, dass der in Abschnitt 5.5 der "Essenz des Iterator-Musters" geäußerte Vorbehalt über exotische Instanzen, die den gleichen Eintrag mehrfach durchlaufen, bereits durch das zweite Gesetz in demselben Papier ausgeschlossen wurde!

+0

Ok, ja, danke, aber wenn ich verspreche, immer verschiedene Teile zu durchlaufen, wie würde ich eine solche Funktion schreiben? – phischu

+0

@phischu In deiner Frage verwendest du nur 'Traversal' als 'Fold', also würde es vielleicht ausreichen, ['ConfedFold'] zu verwenden (https://hackage.haskell.org/package/lens-4.1. 2/docs/Control-Lens-Reified.html # t: VerdingterFold) um verschiedene 'Fold's zu erstellen, zB:' ("hallo", ["world", "!!!"])^.. runFold (Fold _1 <|> Falten (_2.traverse)) ' – fizruk

+0

Es reicht nicht, aber danke! – phischu

Verwandte Themen