2014-05-23 11 views
5

W Control.Lens.Traversal funkcja beside przechodzi przez obie części Bitraversable. Podany przykład jestJak mogę przemierzać różne części struktury danych jedna po drugiej?

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

mogę napisać bardziej wyraźny wersję beside (nazwijmy go bothParts), że zamiast Bitraversable przymusu trwa dwa Traversal s? Wyobrażam sobie, że można go używać w następujący sposób:

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

Czy to już istnieje? Czy to zbyt niebezpieczne, aby można go było używać w zdrowy sposób? Dziękuję Ci!

Edit:

A może coś takiego:

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

Sądzę, że 'bothParts l1 l2' nie zawsze będzie prawidłowym' Traversal'. Rozważmy "bothParts _1 _1" (lub jakikolwiek inny przypadek, w którym nakładają się "l1" i "l2"). – fizruk

Odpowiedz

2

COMBINATOR chcesz powinien użyć 2 Traversal s równocześnie. Ale taki kombinator łamie ogólnie prawa, w szczególności prawo "bez duplikacji": Traversal powinien przechodzić przez każdy element tylko raz.

Oto przykład tego, co prawdopodobnie nie chce:

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

Aby być bardziej precyzyjnym, chciałbym przytoczyć Traversal documentation from lens package:

prawom Przez Traversal t wynikają z prawa dotyczące Traversable zgodnie z "The Essence of the Iterator Pattern".

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

Jedną z konsekwencji tego wymogu jest, że Traversal musi opuścić taką samą liczbę elementów jako kandydata do późniejszego Traversal że zaczęło się. Kolejnym dowodem na siłę tych praw jest to, że zastrzeżenie wyrażone w sekcji 5.5 "Esencji Wzorca Iteratora" o egzotycznych egzemplarzach, które wielokrotnie przemierzały to samo wejście, zostało już wykluczone przez drugie prawo w tym samym artykule!

+0

Ok, tak, dziękuję, ale jeśli obiecuję, że zawsze będę przemierzał różne części, jak mam napisać taką funkcję? – phischu

+0

@phischu w twoim pytaniu używasz 'Traversal's jako' Fold's, więc być może wystarczyłoby ci użyć ['ReifiedFold'] (https://hackage.haskell.org/package/lens-4.1. 2/docs/Control-Lens-Reified.html # t: ReifiedFold) aby skomponować różne 'Fold's, np .:' ("hello", ["world", "!!!"])^.. runFold (fold) _1 <|> Fold (_2.traverse)) ' – fizruk

+0

To nie wystarcza, ale dziękuję! – phischu

Powiązane problemy