Brandon.Si(mmons)

code / art / projects

The Definition of Data.List.group

I’ve been thinking quite a bit lately about a category of functions that are always a bit awkward to define: they involve cases where we would like to traverse a recursive data structure and do something with the data that we have passed over but which is “gone now”. There are many examples of functions like these in the haskell standard libraries: [span](http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#span), [splitAt](http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/GHC-List.html#splitAt), etc.

A function like group is in this category. It’s conceptually very simple, but defining it actually requires a bit of indirection. Here I’ve translated the definition from Data.List to use explicit recursion:

1
2
3
4
5
6
7
8
9
group :: (Eq a) => [a] -> [[a]]
group [] = []
group (a:as) = (a:ys) : group zs
    where (ys,zs) = spanEq as
          spanEq [] = ([], [])
          spanEq (x:xs)
              | a == x = let (ps,qs) = spanEq xs
                          in (x:ps,qs)
              | otherwise = ([], x:xs)

I think if I were asked to define this having never seen it, the first thing I would think of would be something using foldl1, which wouldn’t work.

EDIT: see also an alternative definition for Data.List.groupBy

Comments