Если вы используете контейнер, который является экземпляром FunctorWithIndex
, то вы можете просто использовать imap (,)
:
> imap (,) "abc"
[(0,'a'),(1,'b'),(2,'c')]
Но если индекс не является позицией, это не сработает:
> let m = Map.fromList [('a', "foo"), ('b', "bar"), ('c', "foobar")])
> imap (,) m
fromList [('a',('a',"foo")),('b',('b',"bar")),('c',('c',"foobar"))]
Вместо этого вы можете использовать traversed
, который является индексированным обходом, где индекс представляет собой порядок, в котором отображаются элементы. Это можно использовать для всего, что есть Traversable
. Вместо того, чтобы использовать imap
iover traversed
(который так же, как imapOf
но это было устаревшее):
> iover traversed (,) "abc"
[(0,'a'),(1,'b'),(2,'c')]
> iover traversed (,) m
fromList [('a',(0,"foo")),('b',(1,"bar")),('c',(2,"foobar"))]
Я считаю, 'lens' предлагает индексированную карту, но я не уверен. Я знаю, что если вы используете 'Data.Sequence', гораздо эффективнее использовать' mapWithIndex (,) ', чем любой тип обхода. – dfeuer
'itraverse' конечно делает то, что вы хотите. Какую трудность вы используете? – Carl
@Carl Моя наивная интуиция 'itraverse (,)" abcd "' жалуется на отсутствие экземпляра моноида для Int. Это также похоже на использование '(,)', поскольку первый аргумент дает мне неправильный тип вывода, а именно '(Int, t a)', а не 't (Int, a)'. –