2010-01-09 23 views
12

Kendimi Erik Meijer'in Kanal 9 web yayınlarından Haskell'e öğretmeye çalışan bir C# adamıyım. Zip ve mod kullanarak bir listenin her 'n' öğesini atlamayı içeren ilginç bir bulmacanın karşısına çıktım.Haskell'de sonsuz yinelenen liste nasıl oluşturulur?

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

Bence mod kullanarak önlemek olabilir eğer (gerçekten büyük listeleri veya akışları için) daha verimli olabileceğini düşünüyorum.

Tembel bir yinelenen tamsayılar listesi oluşturarak tembelce düşündüm, böylece basitçe i'nin n değerini karşılaştırabiliriz.

repeatInts :: Int -> [Int] 

şekilde repeatInts 3 döndürür [1,2,3,1,2,3,1,2,3,1,2,3,..] sonsuza çağırarak.

bu göz önüne alındığında, şöyle every yeniden tanımlamak olabilir:

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

Yani benim sorular olduğunu: nasıl repeatInts uygulamak?

+0

Cf. http://stackoverflow.com/questions/2026912/how-to-get-every-nth-element-of-an-infinite-list-in-haskell –

cevap

17

Kullanım cycle:

cycle :: [a] -> [a] 

cycle dairesel birine bağlar sonlu liste veya eş anlamlı olarak orijinal listenin sonsuz tekrarı. Sonsuz listelerdeki kimliktir.

için cycle açısından repeatInts tanımlayabilir: merak için

*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] 

, GHC uygulayan cycle sadece işlevsel dilinde

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

ile, bu ilginç bir teknik, bilinen bir düğümünü düğümünü bağlama d sonsuzdan ziyade döngüsel veri yapıları oluşturur.

ayrıntıları Haskell wiki'de

+0

Teşekkürler, gbacon. Her nasılsa, basit bir cevap olacağını biliyordum! Şimdi 'döngüsünün' çalışmalarına girebiliyorum. –

+0

Garip listeleri olmasa bile, garip bir şekilde, 'çevrim' standart Haskell '98'dir. Kaynağın (yukarıda) ne söylediğini görün - döngüsel bir liste alabilir ya da alamayabilirsiniz ... –

+1

eğlenceli bir şekilde, bu Q/A'nın kendisi XY probleminin bir örneğidir. ;) bir listedeki her öğenin atlanmasının herhangi bir 'mod' içermemesi ve sonsuzluğa sayılmaması gerekir. uygun çözüm ya "zip" ile ($ (0 <$ [2. .n.) ++ ++ [1]) 'ile veya" iterate "ile" splitAt "ile görünüyor. :) –

2

Geç cevap ama t gibi yazılabilir onun:

repeatInts :: Int -> [Int] 
repeatInts 0 = [] 
repeatInts a = [1..a] ++ repeatInts a 
İlgili konular