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?
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]]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With