Somebody suggested I post this here if I wanted feedback.<br>
<br>
So I was thinking about the ReverseState monad I saw mentioned on r/haskell a couple days ago, and playing around with the concept of information flowing two directions when I came up with this function:<br>
<br>
<span class="il">bifold</span> :: (l -&gt; a -&gt; r -&gt; (r,l)) -&gt; (l,r) -&gt; [a] -&gt; (r,l)<br>
<span class="il">bifold</span> _ (l,r) [] = (r,l)<br>
<span class="il">bifold</span> f (l,r) (a:as) = (ra,las)<br>
  where (ras,las) = <span class="il">bifold</span> f (la,r) as<br>        
 (ra,la) = f l a ras<br>
<br>
(I&#39;m sure someone else has come up with this before, so I&#39;ll just say I discovered it, not invented it).<br>
<br>
Basically, it&#39;s a simultaneous left and right fold, passing one value from the start of the list toward the end, and one from the end toward the start.<br>
<br>
It lets you do some interesting stuff, like filter based on positionor other left-dependent information:<br>
<br>
evenIndexed :: [a] -&gt; [a]<br>
evenIndexed = fst . <span class="il">bifold</span> alternate (0,[])<br>
  where alternate 0 x xs = (x:xs, 1)<br>
        alternate 1 _ xs = (xs, 0)<br>
<br>
maximums :: (Ord a) =&gt; [a] -&gt; [a]<br>
maximums [] = []<br>
maximums (a:as) = a : (fst $ <span class="il">bifold</span> (\m a l -&gt; if a &gt; m then (a:l,a) else (l,m)) (a,[]) as)<br>
<br>
As long as you don&#39;t examine the left-to-right value, it can still work on infinite lists:<br>
<br>
ghci&gt; take 20 $ evenIndexed [0..]<br>
[0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38]<br><div id=":120">
<br>
Also, it can be used for corecursive data (or, at least, doubly-linked lists):<br>
<br>
data DList a =  Start { first :: DList a } |<br>
                Entry { value :: a, next :: DList a, prev  :: DList a } |<br>
                End   { last :: DList a }  deriving (Eq)<br>
<br>
ofList :: [a] -&gt; (DList a, DList a)<br>
ofList as = (start,end)<br>
  where start = Start first<br>
        end = End last<br>
        (first,last) = <span class="il">bifold</span> mkEntry (start,end) as<br>
        mkEntry p v n = let e = Entry v n p in (e,e)<br>
<br>
It&#39;s just been running around my head all night, so I thought I&#39;d share.</div>