<div dir="auto">mapWithIndex :: (Int -> a -> b) -> [a] -> [b]<div dir="auto"><span style="font-family:sans-serif">mapWithIndex f = zipWith f [0..]</span><br><div dir="auto"><br></div><div dir="auto">traverseWithIndex :: Applicative f => (Int -> a -> f b) -> [a] -> f [b]<div dir="auto">traverseWithIndex f = sequenceA . mapWithIndex</div><div dir="auto"><br></div><div dir="auto">The real implementation of mapWithIndex (and therefore of traverseWithIndex) can be a "good consumer" for list fusion. mapWithIndex can be a "good producer" as well (which the naive implementation already accomplishes).</div><div dir="auto"><br></div><div dir="auto">Similar functions (with these or similar names) are already common in packages like vector, containers, unordered-containers, and primitive.<br></div><div dir="auto"><br></div><div dir="auto">A more general function would merge zipping with unfolding:</div><div dir="auto"><br></div><div dir="auto">zipWithUnfoldr :: (a -> b -> c) -> (s -> Maybe (b, s)) -> [a] -> s -> [c]</div><div dir="auto"><span style="font-family:sans-serif">zipWithUnfoldr f g as s = zipWith f as (unfoldr g s)</span></div><div dir="auto"><br></div><div dir="auto">But this doesn't seem like the friendliest or most obvious user interface, so I am not proposing to add it to base.</div></div></div></div>