2014-11-01 10 views
8

Ich möchte diese Codezeile map (^?! ix 0) [[0, 1], [4, 5], [9, 1]] um Linsen vollständig zu verwenden, so etwas wie [[0, 1], [4, 5], [9, 1]] & each . ix 0. Die Typen stimmen jedoch nicht überein. Was ist der richtige Weg, dies zu tun?Verwenden Sie Objektiv als `map`

Antwort

10

Verwendung folded:

Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0 
[0,4,9] 

Arbeiten auf jedem Foldable.

Auch wenn Sie planen, immer das erste Element zu extrahieren, wäre es vielleicht klarer, die _head Traversal von Control.Lens.Cons anstelle von ix zu verwenden.

[[0, 1], [4, 5], [9, 1]] ^.. folded . _head 
10

Sie können entweder von

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] 

Die ersten entsprechen genau das, was Sie geschrieben hat, den unsicheren (^?!) Operator, was bedeutet, dass es einen Fehler geben kann. Die zweite ist sicherer, wenn man leere Listen weglässt.

Sie arbeiten auf verschiedene Weise: Die erste erstellt eine modifizierte Version Ihrer ursprünglichen Struktur, die mehr entspricht, was map tut, und es kann auf Strukturen, die keine Listen sind, verwendet werden.

Die zweite erstellt eine Liste Zusammenfassung Ihrer Struktur mit dem Objektiv Falten zur Verfügung gestellt; Obwohl es mit vielen Arten von Strukturen verwendet werden kann, ist das Ergebnis immer eine Liste.

Sie können auch ersetzen each durch traverse (oder, wie @danidiaz weist darauf hin, die etwas allgemeinere traversed) in diesem. Ersteres funktioniert für viele spezielle Dinge wie Tupel, während letzteres für alle Traversable funktioniert.

+1

Vielleicht meinst du 'traversed' von' Control.Lens.Traversal' anstatt von 'traverse'? – danidiaz

+2

@danidiaz Nein, ich meine 'traverse'. Obwohl es nicht von Objektiv ist, wird es als ein wesentlicher Teil davon angesehen. –

+0

@danidiaz Oh ich sehe, * beide * arbeiten hier. Es scheint, dass "Traversed" allgemeiner ist und Indizes erlaubt. –