Есть ли встроенная функция для получения всех последовательных подпоследовательностей размера n списка в Haskell?

Например, мне нужна функция:

gather :: Int -> [a] -> [[a]] gather n list = ??? 

где gather 3 "Hello!" == ["Hel","ell","llo","ol!"] gather 3 "Hello!" == ["Hel","ell","llo","ol!"] .

У меня есть рабочая реализация:

 gather :: Int-> [a] -> [[a]] gather n list = unfoldr (\x -> if fst x + n > length (snd x) then Nothing else Just (take n (drop (fst x) (snd x)), (fst x + 1, snd x))) (0, list) 

но мне интересно, есть ли что-то уже встроенное в язык для этого? Я просмотрел Data.List, но ничего не видел.

Вы можете использовать tails :

 gather nl = filter ((== n) . length) $ map (take n) $ tails l 

или используя takeWhile вместо filter :

 gather nl = takeWhile ((== n) . length) $ map (take n) $ tails l 

EDIT: вы можете удалить шаг фильтра, отбросив последние n элементов списка, возвращаемого из tails как это предлагается в комментариях:

 gather n = map (take n) . dropLast n . tails where dropLast n xs = zipWith const xs (drop n xs) 

Падение хвостов может быть организовано автоматически, благодаря свойствам застежки ,

 import Data.List (tails) g :: Int -> [a] -> [[a]] gn = foldr (zipWith (:)) (repeat []) . take n . tails 

или просто transpose . take n . tails transpose . take n . tails transpose . take n . tails было бы достаточно. Тестирование:

Prelude Data.List> g 3 [1..10]
[[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8], [ 7,8,9], [8,9,10]]
Prelude Data.List> транспонировать. возьмите 3. хвосты $ [1..10]
[[1,2,3], [2,3,4], [3,4,5], [4,5,6], [5,6,7], [6,7,8], [ 7,8,9], [8,9,10], [9,10], [10]]

  • Что представляет собой складку для других типов, кроме списка?
  • Неверный порядок операций ввода-вывода с использованием putStr и getLine
  • Haskell GHC: какова временная сложность совпадения шаблона с конструкторами N?
  • Недостаточная производительность Haskell foldl с (++)
  • Имеет ли Haskell переменные?
  • Что делает оператор infix в Haskell?
  • foldl против foldr с бесконечными списками
  • Что такое монада?
  • Каковы некоторые убедительные варианты использования зависимых типов методов?
  • Конечное понимание бесконечного списка
  • В Haskell, когда мы используем это с let?
  • Давайте будем гением компьютера.