Reputation: 3633
I want to convert this line of code map (^?! ix 0) [[0, 1], [4, 5], [9, 1]]
to entirely use lenses, so something like [[0, 1], [4, 5], [9, 1]] & each . ix 0
. However, the types don't match up. What is the correct way to do this?
Upvotes: 8
Views: 343
Reputation: 27756
Use folded
:
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]
Works on any Foldable
.
Also, if you plan to always extract the first element, perhaps it would be clearer to use the _head
traversal from Control.Lens.Cons
instead of ix
.
[[0, 1], [4, 5], [9, 1]] ^.. folded . _head
Upvotes: 10
Reputation: 18189
You can use either of
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]
The first corresponds to precisely what you wrote, using the unsafe (^?!)
operator, which means that it can give an error. The second is safer by leaving out empty lists.
They work in somewhat different ways: The first creates a modified version of your original structure, which corresponds more to what map
does, and it can be used on structures that aren't lists.
The second creates a list summary of your structure using the lens fold provided; although it can be used with many kinds of structures, the result is always a list.
You can also replace each
by traverse
(or, as @danidiaz points out, the slightly more general traversed
) in this. The former works for many special things like tuples, while the latter works for any Traversable
.
Upvotes: 10