Voglio convertire questa riga di codice map (^?! ix 0) [[0, 1], [4, 5], [9, 1]]
per utilizzare interamente obiettivi, quindi qualcosa come [[0, 1], [4, 5], [9, 1]] & each . ix 0
. Tuttavia, i tipi non corrispondono. Qual è il modo corretto per farlo?Usa obiettivo come `mappa`
risposta
Uso folded
:
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]
Funziona su qualsiasi Foldable
.
Inoltre, se si pianifica di estrarre sempre il primo elemento, forse sarebbe più chiaro utilizzare l'attraversamento _head
da Control.Lens.Cons
anziché ix
.
[[0, 1], [4, 5], [9, 1]] ^.. folded . _head
È possibile utilizzare uno dei
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] & each %~ (^?! ix 0)
[0,4,9]
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. each . ix 0
[0,4,9]
Il primo corrisponde precisamente quello che hai scritto, utilizzando il pericoloso (^?!)
dell'operatore, il che significa che può dare un errore. Il secondo è più sicuro tralasciando le liste vuote.
Lavorano in modi diversi: il primo crea una versione modificata della struttura originale, che corrisponde più a ciò che fa map
e può essere utilizzata su strutture che non sono elenchi.
Il secondo crea un sommario dell'elenco della struttura utilizzando la piegatura dell'obiettivo fornita; sebbene possa essere utilizzato con molti tipi di strutture, il risultato è sempre un elenco.
È inoltre possibile sostituire each
per traverse
(o, come @danidiaz sottolinea, il leggermente più generale traversed
) in questo. Il primo funziona per molte cose speciali come le tuple, mentre il secondo funziona per qualsiasi Traversable
.
Forse intendete "attraversato" da "Control.Lens.Traversal', invece di" traverse "? – danidiaz
@danidiaz No, intendo "traverse". Sebbene non sia * dall'obiettivo *, è considerato una parte essenziale di esso. –
@danidiaz Oh capisco, * entrambi * lavorano qui. Sembra "attraversato" è più generale, consentendo indici. –