The "standard" (or perhaps, famous) way of interleaving lists, back in the jolly days of SICP (and later, Reasoned Scheme), was
infixr 5 ++/
[] ++/ ys = ys
(x:xs) ++/ ys = x:(ys ++/ xs)
It can be used with foldr
,
*Main> foldr (++/) [] [[1,2,3],[4,5,6],[7,8]]
[1,4,2,7,3,5,8,6]
This obviously does not produce the result in the order you wanted, but it will OTOH work OK when the input list of lists is infinite. I don't think there is a way to satisfy both requirements at the same time, as we have no way of knowing whether an input list will be infinite or not.
The above results are what the function insertAtDistance
from Daniel's answer would produce, if modified to always insert at a distance of 1
, instead of d+1
:
insertAtDistance xs (d, ys) = (1, helper d xs ys)
When defined with d+1
it produces "flat" interleaving, whereas foldr (++/) []
produces skewed interleaving:
*Main> take 20 $ foldr (++/) [] [cycle[i] | i<-[1..]]
[1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3]