groupBy "". groupBy (\x y -> x `someComparison` y) someList, x "" , y someList. groupBy someList, y someList. , False. y . , x, someList y.
groupBy (1 st 2 nd 2 nd 3 rd ..), first , . :
groupBy (\x y -> x < y) [1,2,3,2,1] -- returns: [[1,2,3,2],[1]]
groupBy:
- 1 2. 1 < 2, . :
[[1,2]] - 1 3. 1 < 3, , 3 . :
[[1,2,3]] - 1 2. 1 < 2, , 2 . :
[[1,2,3,2]] - 1 1. 1 ≮ 1, , 1 - . :
[[1,2,3,2],[1]]
: , groupBy, , :
groupBy (\x y -> x < y) [1,2,3,4,5,4,3,2,1] -- [[1,2,3,4,5,4,3,2],[1]]
groupBy (\x y -> x < y) [1,3,5,2,1] -- [[1,3,5,2],[1]]
groupBy (\x y -> x <= y) [3,5,3,2,1,0,1,0] -- [[3,5,3],[2],[1],[0,1,0]]
groupBy (\x y -> x <= y) [1,2,3,2,1] -- [[1,2,3,2,1]]
, groupBy , , first . False, , .
, groupBy , :
groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy _ [] = []
groupBy eq (x:xs) = (x:ys) : groupBy eq zs
where (ys,zs) = span (eq x) xs
The key here is to use the function span: span (1<) [2,3,2,1]returns ([2,3,2],[1]). span (eq x) xsin the above code puts all the elements xsthat match (eq x)in the first part of the pair, and the rest xsin the second. (x:ys)then joins xwith the first part of the pair, and is groupByrecursively called in the rest of the pair xs(which is equal zs). That is why it groupByworks in such a strange way.