Учитывая список, я хотел бы разделить его на кластеры, используя «граничную функцию». Такая функция будет принимать два последовательных элемента списка и решать, должны ли они принадлежать одному и тому же кластеру.
По сути, я хочу что-то вроде этого:
clusterBy :: (a -> a -> Bool) -> [a] -> [[a]]
ghci> farAway x y = abs (x - y) > 10
ghci> clusterBy farAway [1, 4, 18, 23, 1, 17, 21, 12, 30, 39, 48]
[[1, 4], [18, 23], [1], [17, 21, 12], [30, 39, 48]]
Поиск этого объявления типа в Hoogle дал только groupBy, что не совсем то, что мне нужно (оно не учитывает порядок элементов).
Есть ли какая-нибудь библиотечная функция, которая делает что-то подобное? Или альтернативно: как это можно реализовать чисто, т.е. не прибегая к циклу хвостовой рекурсии?
EDIT: для справки, реализация, которую мне удалось приготовить, выглядит следующим образом:
clusterBy :: (a -> a -> Bool) -> [a] -> [[a]]
clusterBy isBoundary list =
loop list [] []
where
loop (first:rest) [] result = loop rest [first] result
loop list@(next:rest) cluster result =
if isBoundary (head cluster) next then
loop list [] ((reverse cluster):result)
else
loop rest (next:cluster) result
loop [] cluster@(_:_) result = cluster:result
loop _ _ result = result