Interleave List of Lists in Haskell

后端 未结 4 1984
借酒劲吻你
借酒劲吻你 2020-12-16 23:57

I was wondering how could I write a function in Haskell that interleaves a list of lists into a single lists, for example, if I had a function called

interleav

4条回答
  •  清歌不尽
    2020-12-17 00:04

    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]
    

提交回复
热议问题