Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list of things into a list of sublists

I want to write a function that converts a list of things into a list of sublists, each containing elements of the same value, which when concatenated together give the same list.

So runs [1,2,2,1,3,3,3,2,2,1,1,4] becomes [[1],[2,2],[1],[3,3,3],[2,2],[1,1],[4]]

How do I solve this problem in Haskell?

like image 554
Ahmed hamed aly Avatar asked Oct 16 '20 22:10

Ahmed hamed aly


Video Answer


2 Answers

This function already exists, this is group :: Eq a => [a] -> [[a]]:

Prelude> import Data.List(group)
Prelude Data.List> group [1,2,2,1,3,3,3,2,2,1,1,4]
[[1],[2,2],[1],[3,3,3],[2,2],[1,1],[4]]
like image 143
Willem Van Onsem Avatar answered Sep 27 '22 17:09

Willem Van Onsem


It is often fruitful to check Hoogle when you're looking for a function that might already exist. Because you can search by type, you don't have to know what the function is called. And even if it doesn't exist, it's a good exercise because it makes you think about what type it should have.

Here, the simple type to start with is [a] -> [[a]], but this search yields no results. On reflection this makes sense: you can't split a list of arbitrary objects without some way to compare them.

There are a few ways you might think of to compare list items. One obvious one, since you want to group items that are equal, is Eq. So you might try a search for Eq a => [a] -> [[a]], and this in fact yields group. You might similarly try Ord a instead, since Ord is another way to compare things, but this yields no results.

Lastly you might try the most general thing possible: take in a predicate function dictating where to split the list. A search for (a -> a -> Bool) -> [a] -> [[a]] yields groupBy, which is another reasonable way of achieving your goal, though in fact more general than necessary.

like image 39
amalloy Avatar answered Sep 27 '22 18:09

amalloy