Roundup on proposal 3671 [was: Re: Proposal (Trac ticket #3671): Add takeRec, genericTakeRec and spanRec to Data.List]

Philip K.F. Hölzenspies p.k.f.holzenspies at
Wed Nov 25 06:56:01 EST 2009

Dear Christian, et al.

Thanks for the summary, Christian. I've given some detailed comments
below, but I'll give the gist here.

The ticket has indeed moved on quite a bit. Some more expressive
functions were proposed that weren't part of the ticket, but that maybe
should have been. Some of the originally proposed functions can be
expressed easily in these more expressive ones and, therefore, may not
be wanted inclusions any more.

I suggest we get everyone to +1 or -1 on the following list of possible
new inclusions (where the slash-separated list of names all represent
the same function - for +1s also indicate name preference):

- takeRec / splitAts / groupsOf / segmentsOf :: Int -> [a] -> [[a]]
- genericTakeRec / genericSplitAts / genericGroupsOf /
genericSegmentsOf :: Integral i => i -> [a] -> [[a]]
- spanRec / spans :: (a -> Bool) -> [a] -> [[a]]
- breakRec / breaks :: (a -> Bool) -> [a] -> [[a]]
- runs :: (a -> a -> Bool) -> [a] -> [[a]]
- run :: (a -> a -> Bool) -> [a] -> ([a],[a])
- replace :: Eq a => [a] -> [a] -> [a] -> [a]
- replaceBy :: ([a] -> (b, [a])) -> [a] -> [b]

The implementations of the chosen functions should, in my mind, be based
on profiling results.

As an open procedural question: can a proposal track ticket be
obsolidated by a new ticket? What is the common procedure for revising a


On Tue, 2009-11-24 at 10:23 +0100, Christian Maeder wrote:
> Ok, lets try to get back to the proposal.

Good idea. I think there is general consensus that *something* along
these lines should be added, but we have to agree on what. Clearly, the
original proposal has undergone such revision that we might want to
obsolidate it. Is there a replacement procedure for Trac proposals?

> 1. We want something like takeRec being named splitAts or groupsOf
> (groupsOf is too similar to the existing groupsBy)

Although I liked groupsOf, I see your point. Suggestion for alternative:


> 2. genericTakeRec is just a variant of takeRec based on genericSplitAt
> rather than splitAt (or genericTake, genericDrop instead of take, drop)

Correct, but whatever it's going to be called, a genericX variant seems

> 3. spanRec changed to a mutual recursive implementation for spans and
> breaks (in the ticket) that is not supported much. Rather breaks was
> more discussed in this thread as a splitting function (that was
> discussed years before under splitBy or splitOn without any agreement.)
> Agreement seems to be about "breaks p = spans (not . p)" (or vice versa)
> Furthermore, proposal for runs (4.) and replace (5.) came up in this
> thread, that are not part of the ticket.

You're absolutely right about this and I feel it would be better to fix
this. Hence: Is there a replacement procedure for a proposal ticket?

> 4. I find "runs" useful in the sense proposed by Philip with type
>   runs :: (a -> a -> Bool) -> [a] -> [[a]]
> > runs (<) [1,2,3,4,3,4,5]
> [[1,2,3,4],[3,4,5]]
> (there's no proposal to rename groupsBy)
> 5. The type of my replace function was:
>   replace :: Eq a => [a] -> a -> [a] -> [a]
> and a (reasonable) alternative would be to replace a sublist by another
> sublist and not by a single element.

I actually thought your replaceBy was very nice, especially because it
allows for the expression of all the other functions. Most
significantly, the '[b]' result type really works for me.

> Which of the above functions (1. - 4.) should be part of the proposal?

Methinks 1-5, no?

> How should these functions be implemented?
> I only made a proposal how they could be implemented using replaceBy
> (below), but direct recursive definitions may be more appropriate.
> I.e. unlines and unwords are also defined with explicit recursion
> although alternative definitions are there (based on concatMap and foldr1)

I think implementation choices should depend more than anything on
performance. As I remarked somewhere else in this thread, performance
might very well be a sliding argument over different compiler versions.
I would propose we first vote on the functions we want in there (it
seems that also determines some of the implementation choices available)
and then to just profile the alternative implementations.

More information about the Libraries mailing list