Data.List.groupBy with non-transitive equality predicate

Donald Bruce Stewart dons at cse.unsw.edu.au
Thu Aug 30 08:03:53 EDT 2007


duncan.coutts:
> On Wed, 2007-08-29 at 22:02 +0200, Henning Thielemann wrote:
> > I was used to use groupBy to split a list before every element that
> > satisfies a predicate. E.g. splitting before every capital
> > 
> > Prelude> groupBy (\_ c -> not $ Char.isUpper c) "Hello World"
> > ["Hello ","World"]
> > 
> > I also wanted to use this for splitting after specific elements.
> > But this fails. I get
> > 
> > Prelude> groupBy (\c _ -> c /= ',') "1, 2, 3, 4"
> > ["1, 2, 3, 4"]
> > 
> > but I wanted
> > ["1,", " 2,", " 3,", " 4"]
> > 
> >  I assumed that 'groupBy' would compare adjacent elements, but it seems to
> > compare the leading element of each block with subsequent elements. Since
> > the documentation doesn't tell which elements are actually compared it
> > seems to assume that the comparison is commutative and transitive. Maybe
> > this point should be made clearer.
> >  Additionally I think that comparing neighbouring elements is a useful
> > behaviour and I suggest an according variant of 'groupBy' for Data.List.
> > Opinions?
> 
> I noticed this interesting behaviour when implementing groupBy for lazy
> bytestrings. My QC tests showed I had the wrong answer for
> non-transative predicates. It was actually a lot harder to implement the
> H98 behaviour than the behaviour where we compare adjacent elements. So
> purely from an implementation point of view I'd be happy to change the
> behaviour to that which you suggest.
> 

I'd second this. groupBy's exact behaviour was really fiddly to nail down in QC. 
H' should come with QuickCheck properties relating list functions to
each other.

-- Don


More information about the Libraries mailing list