Here's one that does what you want, doesn't require the list to be sorted, and groups together consecutive and equal terms:

groupConsecutive :: (Enum a,Eq a) => [a] -> [[a]]
groupConsecutive = foldr go []
    where go x ls@(hd@(y:_):yss)
            | x == y || x == pred y = (x:hd):yss
            | otherwise             = [x]:ls
          go x [] = [[x]]
          go x ([]:yss) = [x]:yss

Then
> groupConsecutive [1,2,3,7,8,10,11,12]
[[1,2,3],[7,8],[10,11,12]]

> groupConsecutive [1,2,2,3,2,3]
[[1,2,2,3],[2,3]]

and
> groupConsecutive "bookkeeper understudy"
["b","oo","kk","ee","p","e","r"," ","u","n","de","rstu","d","y"]

The third case of go will never be reached. If you use a type that is also an instance of Bounded, and if your list contains the minimum element of the type, you'll get a runtime error on the use of pred. For example:

> groupConsecutive [True,False,True]
*** Exception: Prelude.Enum.Bool.pred: bad argument

Graham

On 13-Jan-2017 11:05 AM, Saqib Shamsi wrote:
Hi,

The problem that I wish to solve is to divide a (sored) list of integers into sublists such that each sublist contains numbers in consecutive sequence.

For example,
Input: [1,2,3,7,8,10,11,12]
Output: [[1,2,3],[7,8],[10,11,12]]

I have written the following code and it does the trick.

-- Take a list and divide it at first point of non-consecutive number encounter
divide :: [Int] -> [Int] -> ([Int], [Int])
divide first [] = (first, [])
divide first second = if (last first) /= firstSecond - 1 then (first, second)
                      else divide (first ++ [firstSecond]) (tail second)
                      where firstSecond = head second


-- Helper for breaking a list of numbers into consecutive sublists
breakIntoConsecsHelper :: [Int] -> [[Int]] -> [[Int]]
breakIntoConsecsHelper [] [[]] = [[]]
breakIntoConsecsHelper lst ans = if two == [] then ans ++ [one]
                                 else ans ++ [one] ++ breakIntoConsecsHelper two []
                                 where
                                      firstElem = head lst
                                      remaining = tail lst
                                      (one, two) = divide [firstElem] remaining


-- Break the list into sublists of consective numbers
breakIntoConsecs :: [Int] -> [[Int]]
breakIntoConsecs lst = breakIntoConsecsHelper lst [[]]

-- Take the tail of the result given by the function above to get the required list of lists.

However, I was wondering if there was a better way of doing this. Any help would be highly appreciated.

Thank you.
Best Regards,
Saqib Shamsi


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners