Как создать бесконечно повторяющийся список в Haskell?

Я - парень C#, пытающийся преподавать мне Haskell от вебкастов Канала 9 Erik Meijer. Я столкнулся с интересной загадкой, которая включила пропуск каждый 'n' элементы списка с помощью zip и модификации.

every :: Int -> [a] -> [a]
every _ [] = []
every n xs = [x | (x,i) <- zip xs [1..], i `mod` n == 0]

Я думал, что это могло бы быть более эффективно (для действительно больших списков или потоков), если мы могли бы избегать использования модификации.

Я думал о ленивом создании повторяющегося списка целых чисел, таким образом, мы можем просто сравнить значение меня к n.

repeatInts :: Int -> [Int]

таким образом, что вызов repeatInts 3 возвраты [1,2,3,1,2,3,1,2,3,1,2,3,..] до бесконечности.

Учитывая это, мы могли переопределить every как так:

every :: Int -> [a] -> [a]
every _ [] = []
every n xs = [x | (x,i) <- zip xs (repeatInts n), i == n]

Так мои вопросы: как Вы реализовали бы repeatInts?

13
задан Don Stewart 18 April 2011 в 18:37
поделиться

1 ответ

Используйте цикл :

 Цикл :: [A] -> [A]
 

Цикл соединяет конечный список в круговой или эквивалентно, бесконечное повторение исходного списка. Это личность в бесконечных списках.

Вы могли бы определить Repreeints в терминах цикла :

*Main> let repeatInts n = cycle [1..n]
*Main> :t repeatInts
repeatInts :: (Num t, Enum t) => t -> [t]
*Main> take 10 $ repeatInts 3
[1,2,3,1,2,3,1,2,3,1]

для любопытных, ГККализатор цикл с

cycle [] = errorEmptyList "cycle"
cycle xs = xs' where xs' = xs ++ xs'

в чисто функциональном языке, это Любопытная техника известна как , связывая узел , и он создает циклические структуры данных, а не бесконечные.

Подробнее см.

21
ответ дан 1 December 2019 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: