I recently learned about difference lists, and how they can be used for efficient concatenation in Haskell. I learned how they actually work through this article: Demystifying DList
When defunctionalized, it seems like a difference list is a data structure that is made of a tree of normal lists, and when you want to convert one to a normal list, you flatten the tree of lists into a list of sublists (abusing the ($)
operator as a cons cell, and the sublists being actually closures that capture the sublists), which are then concatenated.
In one chapter of Learn You A Haskell, the author compares the repeated left-associated concatenation of lists to difference lists when demonstrating the Writer monad.
This is pretty interesting, but it makes me wonder: why does the Writer monad require a type that can be appended associatively (i.e. a Monoid)? When logging, aren’t you only ever going to add one item to the list at a time and only at one end? Why does it do the equivalent of [firstReport, secondReport, ...] ++ [newReport]
instead of newReport : [..., secondReport, firstReport]
? That is, why do you have to have logs that append Monoids instead of just providing an item to add to the log history? Then, you wouldn’t need something like the difference list to make up for this behavior in the first place. When would you need to join concatenate two arbitrarily long log histories together?