encode = map (length &&& head) . group
Which produces RLE'd tuples:
> encode "aaaabbaaa"
[(4,'a'),(2,'b'),(3,'a')]
But what's this
&&&
bit? It's from Control.Arrow, the implementation of arrows, which are reportedly a generalization of monads. The last time I tried to look at this was before I grokked monads so it's probably worth another look, but the superficial understanding needed here is that &&&
runs two functions "in parallel" (not as in simultaneously, just in that they're not interacting) and produces a pair of their two outputs.That is,
> :t length &&& head
length &&& head :: [a] -> (Int, a)
where the first component of the tuple is the length and the second is the head of the list.
What a peculiar but also imaginably useful operator! (Of course, in the arrows docs the application of this just to functions is the most basic of the many generalizations.)