<div dir="ltr">I propose adding two new functions to Data.List:<br><br>    zipConsecutives :: [a] -> [(a,a)]<br>    zipConsecutives xs = zip xs (tail xs)<br><br>    zipConsecutivesWith :: (a -> a -> b) -> [a] -> [b]<br>    zipConsecutivesWith f xs = zipWith f xs (tail xs)<br><br>(with possibly more efficient implementations)<br><br>The Trac feature request is at <a href="https://ghc.haskell.org/trac/ghc/ticket/11815">https://ghc.haskell.org/trac/ghc/ticket/11815</a>.<br><br><br>Why<br><br>These functions are useful when one wants to process consecutive pairs<br>of elements in a sequence, which is not uncommon. The ticket lists<br>some examples, reiterated here:<br><br>    -- diff consecutive elements:<br>    diffs = zipConsecutivesWith (flip (-))<br><br>    -- determine if list is ascending (similar for descending and strict):<br>    isAscending = and . zipConsecutivesWith (<=)<br><br>    -- an old friend of ours:<br>    fibs = 1 : 1 : zipConsecutivesWith (+) fibs<br><br>    -- get the edges of a closed path defined by points (ps):<br>    edges ps = zipConsecutivesWith makeEdge (ps ++ take 1 ps)<br><br><br>Why add to Data.List (and base)<br><br>The definition must either use an extra equation for the empty list case:<br><br>    zipConsecutives [] = []<br>    zipConsecutives xs = zip xs (tail xs)<br><br>which makes it non practical to define inline at each use site. Or one<br>may omit the empty list equation, which is safe (thanks to laziness),<br>but that may not be immediately obvious. (It wasn't to me anyway.) The<br>tail function is generally considered unsafe so it is not desirable to<br>force the user to use it. The proposed functions would offer an<br>alternative.<br><br><br>The Data.List module is often imported unqualified, so new identifiers<br>may cause collissions. I do find it rather unlikely that the proposed<br>names would cause such problems, however.<br><br><br>Deadline for discussion: 2016-05-31.<br></div>