Use structural induction on the finite list xs, strengthening the induction hypothesis to hold for every accumulator value . For the empty list, the defining equation of the left fold gives
For the inductive step, suppose the identity holds for the tail zs and every accumulator. Expand the first left fold, apply the induction hypothesis at accumulator , and then use the supplied compatibility law:
Hence
Only equation (1) is needed for this part; the seed condition in equation (2) enters the next proof. Quantifying over the accumulator is essential because the recursive call changes it.
Again use structural induction on the finite list. At [], both the right fold and the left fold return the seed . If they agree on zs, then
The third line uses part (a); the fourth uses equation (2). Thus the left-right fold equivalence is
This is a statement about values on finite, total inputs. It does not assert equal evaluation costs or equal behaviour on infinite lists.
Use list concatenation as the combining operation and the empty list as the seed:
concat :: [[a]] -> [a]
concat = foldr (++) []
For three inner lists, this constructs xs ++ (ys ++ (zs ++ [])), preserving the elements' original order. The concise answer is .
Set both and equal to list concatenation, with . Associativity gives xs ++ (ys ++ zs) = (xs ++ ys) ++ zs, which is equation (1). The two identity laws give xs ++ [] = [] ++ xs, which is equation (2). Part (b) therefore yields
concat :: [[a]] -> [a]
concat = foldl (++) []
Thus on finite lists. The argument order is unchanged: the accumulator is the already concatenated prefix, and the next inner list is appended to its right. This preserves the order but repeatedly copies that prefix.
Let there be inner lists, of lengths , and let . Evaluate the whole output list spine, taking each input element as an already available value. The defining equation (x:xs) ++ ys = x : (xs ++ ys) shows that list concatenation traverses its left operand, sharing its right operand.
The right fold puts each original inner list on the left of exactly one concatenation. Thus its total element traversal is proportional to , and visiting the outer list costs :
The term matters when many inner lists are empty. With rows each of length , the bound is . In particular, with uniformly bounded positive row length it is linear in .
Write , with . At the th step of the left fold, the left operand of list concatenation is the accumulated prefix of length . Fully forcing these concatenations repeatedly copies earlier elements. Including the traversal of the outer list and the whole output spine gives
For singleton inner lists, this becomes , whereas the right fold takes . More generally, for equal positive length , the left fold takes .
An bound is tight in the worst case over length distributions, but is not a tight formula for every distribution: if all elements occur only in the final inner list, all earlier accumulators are empty and the cost is . Lazy evaluation changes when the work happens; it does not remove repeated prefix traversal when the whole result is demanded.

Articles by others on the same topic (0)

There are currently no matching articles.