<div dir="ltr">I want to point out that there already exist Haskell package `ilist` that provides indexed versions of each function for the list from `base`:<div><br></div><div>* <a href="http://hackage.haskell.org/package/ilist">http://hackage.haskell.org/package/ilist</a><br><br>This package comes with optimized implementations and custom fusion rules. For example `mapWithIndex` is called `imap` and is implemented like this:</div><div><br></div><div><pre style="color:rgb(0,0,0)"><span class="gmail-hs-comment" style="color:green">{- |
<a name="line-243" style="color:green"></a>/Subject to fusion./
<a name="line-244" style="color:green"></a>-}</span>
<a name="line-245"></a><span class="gmail-hs-definition">imap</span> <span class="gmail-hs-keyglyph" style="color:red">::</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-conid">Int</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">a</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">b</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-keyglyph" style="color:red">[</span><span class="gmail-hs-varid">a</span><span class="gmail-hs-keyglyph" style="color:red">]</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-keyglyph" style="color:red">[</span><span class="gmail-hs-varid">b</span><span class="gmail-hs-keyglyph" style="color:red">]</span>
<a name="line-246"></a><span class="gmail-hs-definition">imap</span> <span class="gmail-hs-varid">f</span> <span class="gmail-hs-varid">ls</span> <span class="gmail-hs-keyglyph" style="color:red">=</span> <span class="gmail-hs-varid">go</span> <span class="gmail-hs-num">0</span><span class="gmail-hs-cpp">#</span> <span class="gmail-hs-varid">ls</span>
<a name="line-247"></a>  <span class="gmail-hs-keyword" style="color:blue">where</span>
<a name="line-248"></a>    <span class="gmail-hs-varid">go</span> <span class="gmail-hs-varid">i</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-varid">x</span><span class="gmail-hs-conop">:</span><span class="gmail-hs-varid">xs</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-keyglyph" style="color:red">=</span> <span class="gmail-hs-varid">f</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-conid">I</span><span class="gmail-hs-cpp">#</span> <span class="gmail-hs-varid">i</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-varid">x</span> <span class="gmail-hs-conop">:</span> <span class="gmail-hs-varid">go</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-varid">i</span> <span class="gmail-hs-varop">+#</span> <span class="gmail-hs-num">1</span><span class="gmail-hs-cpp">#</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-varid">xs</span>
<a name="line-249"></a>    <span class="gmail-hs-varid">go</span> <span class="gmail-hs-keyword" style="color:blue">_</span> <span class="gmail-hs-keyword" style="color:blue">_</span> <span class="gmail-hs-keyglyph" style="color:red">=</span> <span class="gmail-hs-conid">[]</span>
<a name="line-250"></a><span class="gmail-hs-comment" style="color:green">{-# NOINLINE [1] imap #-}</span></pre><pre style="color:rgb(0,0,0)"><span class="gmail-hs-comment" style="color:green"><pre style="color:rgb(0,0,0)"><span class="gmail-hs-definition">imapFB</span>
<a name="line-253"></a>  <span class="gmail-hs-keyglyph" style="color:red">::</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-varid">b</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">t</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">t</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-conid">Int</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">a</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">b</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">a</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-conid">Int</span><span class="gmail-hs-cpp">#</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">t</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-conid">Int</span><span class="gmail-hs-cpp">#</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">t</span>
<a name="line-254"></a><span class="gmail-hs-definition">imapFB</span> <span class="gmail-hs-varid">c</span> <span class="gmail-hs-varid">f</span> <span class="gmail-hs-keyglyph" style="color:red">=</span> <span class="gmail-hs-keyglyph" style="color:red">\</span><span class="gmail-hs-varid">x</span> <span class="gmail-hs-varid">r</span> <span class="gmail-hs-varid">k</span> <span class="gmail-hs-keyglyph" style="color:red">-></span> <span class="gmail-hs-varid">f</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-conid">I</span><span class="gmail-hs-cpp">#</span> <span class="gmail-hs-varid">k</span><span class="gmail-hs-layout" style="color:red">)</span> <span class="gmail-hs-varid">x</span> <span class="gmail-hs-varop">`c`</span> <span class="gmail-hs-varid">r</span> <span class="gmail-hs-layout" style="color:red">(</span><span class="gmail-hs-varid">k</span> <span class="gmail-hs-varop">+#</span> <span class="gmail-hs-num">1</span><span class="gmail-hs-cpp">#</span><span class="gmail-hs-layout" style="color:red">)</span>
<a name="line-255"></a><span class="gmail-hs-comment" style="color:green">{-# INLINE [0] imapFB #-}</span>
<a name="line-256"></a>
<a name="line-257"></a><span class="gmail-hs-comment" style="color:green">{-# RULES
<a name="line-258" style="color:green"></a>"imap"       [~1] forall f xs.    imap f xs = build (\c n -> foldr (imapFB c f) (\_ -> n) xs 0#)
<a name="line-259" style="color:green"></a>"imapList"   [1]  forall f xs.    foldr (imapFB (:) f) (\_ -> []) xs 0# = imap f xs
<a name="line-260" style="color:green"></a>  #-}</span></pre></span></pre></div><div><br></div><div>I'm not trying to say that we shouldn't have `mapWithIndex` in `base`. But the implementation for lists already exists and the inspiration about the implementation can be taken from it.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Aug 17, 2019 at 9:17 AM David Feuer <<a href="mailto:david.feuer@gmail.com">david.feuer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><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>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>