Is there a nicer way to do the equivalent of Haskell indexed :: [a] -> [(Int, a)]
other than:
zip [0..length a] a
Is there a nicer way to do the equivalent of Haskell indexed :: [a] -> [(Int, a)]
other than:
zip [0..length a] a
This is somewhat similar to Map over list with running index. I think your solution is fine but length
traverses the list once and then zip
does again so it’s not super efficient.
For a more efficient solution either use the zipWith
function from the linked post or if you really want to squeeze every last interpreter cycle out of it, inline the function into zipWith
:
indexed : [a] -> [(Int, a)]
indexed as =
fst $ foldr (\a (bs, i) -> ((i, a) :: bs, i + 1)) ([], 0) as
That said, while I think the switch to the efficient mapWithIndex
will bring measurable improvements (in macrobenchmarks, always hard to say how it translates to a full app), the inlining benefits should be tiny and I personally wouldn’t bother with that unless you have the benchmarks to back it up.
Shouldn’t this be instead:
indexed as = fst $ foldr (\a (bs, i) -> ((i, a) :: bs, i - 1)) ([], length as - 1)
ah right sorry wrong direction, you could try
indexed as =
reverse $ fst $ foldl (\(bs, i) a -> ((i, a) :: bs, i + 1)) ([], 0) as
which might be a tiny bit faster but tbh I doubt at that point it matters much compared to the zip
solution.