rolling span and groupBy for lists

Evan Laforge qdunkan at gmail.com
Mon Feb 5 06:52:08 UTC 2018


I have my own list library with a bunch of things like this.  I think
it's what most people do, and some upload them to hackage, e.g.
utility-ht or the split package, or data-ordlist.

Specifically, I think rollingGroupBy is what I call splitWith:

-- | Split @xs@ before places where @f@ matches.
--
-- > split_with (==1) [1,2,1]
-- > --> [[], [1, 2], [1]]
split_with :: (a -> Bool) -> [a] -> NonNull [a]
    -- ^ output is non-null, and the contents are also, except the first one

You can probably find something like this in 'split', or if not, that
might be a good place to contribute it.

I have a bunch of grouping functions too, which I use all the time, so
if there's some kind of general list grouping package then maybe I
could put them there.

On the other hand, this sort of thing is pretty individual, so it
doesn't seem so bad for each person to have their own local library.
That way you know it fits your style.  Ultimately I think that's why
none of the split functions made it into Data.List, every person has a
slightly different idea of what it should be.

On Sun, Feb 4, 2018 at 7:50 PM, Harendra Kumar <harendra.kumar at gmail.com> wrote:
> Hi,
>
> For a small problem, I was looking for a groupBy like function that groups
> based on a predicate on successive elements but I could not find one. I
> wrote these little functions for that purpose:
>
> -- | Like span, but with a predicate that compares two successive elements.
> The
> -- span ends when the two successive elements do not satisfy the predicate.
> rollingSpan :: (a -> a -> Bool) -> [a] -> ([a], [a])
> rollingSpan _ xs@[] = (xs, xs)
> rollingSpan _ xs@[_] = (xs, [])
> rollingSpan p (x1:xs@(x2:_))
>     | p x1 x2 =
>         let (ys, zs) = rollingSpan p xs
>         in (x1 : ys, zs)
>     | otherwise = ([x1], xs)
>
> -- | Like 'groupBy' but with a predicate that compares two successive
> elements.
> -- A group ends when two successive elements do not satisfy the predicate.
> rollingGroupBy :: (a -> a -> Bool) -> [a] -> [[a]]
> rollingGroupBy _ [] = []
> rollingGroupBy cmp xs =
>     let (ys, zs) = rollingSpan cmp xs
>     in ys : rollingGroupBy cmp zs
>
> Are there any existing functions that serve this purpose or is there any
> simpler way to achieve such functionality? If not, where is the right place
> for these, if any. Can they be included in Data.List in base?
>
> Thanks,
> Harendra
>
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>


More information about the ghc-devs mailing list