2014-05-23 6 views
5

In Control.Lens.Traversal la funzione beside attraversa entrambe le parti di un Bitraversable. L'esempio dato èCome posso attraversare le diverse parti della struttura dati una dopo l'altra?

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

Posso scrivere una versione più esplicita di beside (chiamiamolo bothParts) che invece di un vincolo Bitraversable prende due Traversal s? Immagino che sia usato così:

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

Esiste già? È troppo pericoloso essere usato in modo sano? Grazie!

Edit:

O forse qualcosa di simile:

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

Penso che 'bothParts l1 l2' non sarà sempre un valido' Traversal'. Considera 'bothParts _1 _1' (o qualsiasi altro caso in cui' l1' e 'l2' si sovrappongono). – fizruk

risposta

2

il combinatore si desidera si suppone di utilizzare 2 Traversal s contemporaneamente. Ma questo tipo di combinatore rompe le leggi Traversal in generale, in particolare la legge "nessuna duplicazione": un Traversal dovrebbe attraversare ogni elemento solo una volta.

Ecco un esempio di ciò che probabilmente non si vuole:

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

Per essere più precisi, vorrei citare Traversal documentation from lens package:

Le leggi per un Traversal t seguito dal leggi per Traversable come indicato in "The Essence of the Iterator Pattern".

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

Una conseguenza di questo requisito è che un Traversal necessità di lasciare lo stesso numero di elementi come candidato per la successiva Traversal che è iniziato con. Un altro testamento alla forza di queste leggi è che l'avvertenza espressa nella sezione 5.5 della "Essenza del Pattern Iterator" sulle esotiche Traversable istanze che attraversano la stessa voce più volte era in realtà già esclusa dalla seconda legge in quella stessa carta!

+0

Ok, sì, grazie, ma se prometto di attraversare sempre diverse sottoparti, come potrei scrivere una tale funzione? – phischu

+0

@phischu nella tua domanda usi solo 'Traversal's come' Fold's, quindi forse sarebbe sufficiente per te usare ['ReifiedFold'] (https://hackage.haskell.org/package/lens-4.1. 2/docs/Control-Lens-Reified.html # t: ReifiedFold) per comporre diversi 'Fold's, ad esempio:' ("ciao", ["mondo", "!!!"])^.. runFold (Fold _1 <|> Fold (_2.traverse)) ' – fizruk

+0

Non è sufficiente, ma grazie! – phischu

Problemi correlati