Что это за шаблон складывания и итерации? - PullRequest
6 голосов
/ 18 марта 2012

Представьте, что вам нужно сложить последовательность и узнать также промежуточные значения в нескольких точках диапазона. Вот что я использовал для этого:

[a,b,c] = map fst . tail $ chain [g i, g j, g k] (zero, sequence)

g :: Integer -> (a,b) -> (a,b)

chain (f:fs) x = x : chain fs (f x)
chain [] x = [x]

Функция g потребляет определенную часть входной последовательности (длиной i, j и т. Д.), Начиная с некоторого начального значения и производя результаты того же типа, для передачи в следующую призывание. Потребление последовательности несколько раз для разных длин, начинающихся с начала и одного и того же начального значения, было бы неэффективным, конечно, как во времени, так и в пространстве.

Итак, с одной стороны, мы складываем эту последовательность целых чисел - промежуточные точки последовательности; с другой стороны, мы повторяем эту функцию, g. Что это? Я что-то упустил здесь? Можно ли это как-то выразить с помощью регулярного репертуара складок и т. Д.?

РЕДАКТИРОВАТЬ: Решено: выше просто

[a,b,c] = map fst . tail $ scanl (flip g) (zero, sequence) [i, j, k] 

интересно, как на самом деле модифицируемая итерация сворачивается в список модификаторов.

Ответы [ 2 ]

9 голосов
/ 18 марта 2012

Попробуйте scanl: http://www.haskell.org/hoogle/?hoogle=scanl

scanl похож на foldl, но возвращает список последовательных сокращений значения слева:

scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]

Обратите внимание, что

last (scanl f z xs) == foldl f z xs
4 голосов
/ 18 марта 2012

Чтобы уточнить комментарий Марцина, вы, в основном, хотите:

intermediates = scanl step zero sequence
map (\n -> intermediates !! n) [i, j, k]

step - это не g, а просто часть g, которая потребляет один элемент списка sequence.

Кроме того, примите ответ Марцина как правильный ответ.

...