Haskell合并两个列表,每次都增加每个列表中每个块的大小

Haskell合并两个列表,每次都增加每个列表中每个块的大小,haskell,Haskell,需要在Haskell中创建一个函数,该函数接受两个列表并产生 将两个输入列表中的所有元素组合在一起的列表,从第一个列表中取1,从第二个列表中取2,从第一个列表中取3,从第二个列表中取4,以此类推,直到两者都用尽为止 例如: weaveHunks [1,2,3,4,5,6,7,8] [11,12,13,14,15,16,17,18] => [1,11,12,2,3,4,13,14,15,16,5,6,7,8,17,18] 到目前为止,我有一个函数,给定一个数字n和两个列表,它将把两个给定的

需要在Haskell中创建一个函数,该函数接受两个列表并产生 将两个输入列表中的所有元素组合在一起的列表,从第一个列表中取1,从第二个列表中取2,从第一个列表中取3,从第二个列表中取4,以此类推,直到两者都用尽为止

例如:

weaveHunks [1,2,3,4,5,6,7,8] [11,12,13,14,15,16,17,18]
=> [1,11,12,2,3,4,13,14,15,16,5,6,7,8,17,18]
到目前为止,我有一个函数,给定一个数字n和两个列表,它将把两个给定的列表合并成大小为n的块

weaveHunks :: Int -> [a] -> [a] -> [a]
weaveHunks _ xs [] = xs
weaveHunks _ [] ys = ys
weaveHunks n xs ys = xHunk ++ yHunk ++ weaveHunks n xRemain yRemain
 where [(xHunk, xRemain), (yHunk, yRemain)] = splitAt n <$> [xs,ys]
weaveHunks::Int->[a]->[a]->[a]
weaveHunks xs[]=xs
weaveHunks[uuys=ys
weaveHunks n xs ys=xHunk++yHunk++weaveHunks n xyremain
式中[(xHunk,xRemain),(yHunk,yRemain)]=splitAt n[xs,ys]
尝试扩展这个答案,所以我不想给它一个定义块大小的参数,而是想在每次递归调用函数时增加一个计数器

在这里,我不确定您将如何创建某种计数器,以便在每次调用函数时增加块大小。我无法向上面的函数传递数字,因为它只有两个参数是两个列表。我曾考虑过使用某种辅助函数,每次weaveHunks运行时都会保持一个递增的计数器,但我认为这也不是一个可行的选择


是否有一种不同的方式不依赖于递增计数器?我觉得我应该使用
succ
操作符来完成我要做的事情

这里可能缺少的是一个累加器,它可以递增,这样我们就知道从第一个和第二个列表中可以得到多少

如果我理解正确,这里基本上有两种情况:

  • 如果两个列表都已用尽,则结果为空列表;及
  • 如果两个列表中至少有一个不是空的,我们从第一个列表中获取
    n
    元素,从第二个列表中获取
    n+1
    元素,然后对列表的其余元素进行递归,但现在使用
    n+2
    ,这意味着我们定义了一个函数,如:
  • 或者,我们可以每次从第一个列表中提取
    n
    ,然后使用
    n+1
    递归并交换列表,如:

    import Data.List(splitAt)
    
    weaveHunks :: [a] -> [a] -> [a]
    weaveHunks = go 1
        where go _ [] [] = []
              go n la lb = aa ++ go (n+1) lb ab
                  where (aa, ab) = splitAt n la

    这里可能缺少一个递增的累加器,这样我们就知道从第一个和第二个列表中可以得到多少

    如果我理解正确,这里基本上有两种情况:

  • 如果两个列表都已用尽,则结果为空列表;及
  • 如果两个列表中至少有一个不是空的,我们从第一个列表中获取
    n
    元素,从第二个列表中获取
    n+1
    元素,然后对列表的其余元素进行递归,但现在使用
    n+2
    ,这意味着我们定义了一个函数,如:
  • 或者,我们可以每次从第一个列表中提取
    n
    ,然后使用
    n+1
    递归并交换列表,如:

    import Data.List(splitAt)
    
    weaveHunks :: [a] -> [a] -> [a]
    weaveHunks = go 1
        where go _ [] [] = []
              go n la lb = aa ++ go (n+1) lb ab
                  where (aa, ab) = splitAt n la

    嗨,欢迎!为了正确理解您的问题:您有一个主函数
    weaveHunks::[a]->[a]->[a]
    (上面的“函数作为其仅有的两个参数是两个列表”),您还有另一个辅助函数,它应该有另一个名称,即
    weaveHunksAux::Int->[a]->[a]
    ,对吗,您对主函数weaveHunks的看法是正确的,它接收两个列表并输出一个列表,该列表是将两个给定列表编织在一起的结果,每次都增加两个给定列表中每个块的大小。辅助功能只是我的想法,我可以保留一个计数器,这样每次我都可以增加块的大小,这不是实际问题的一部分。嗨,欢迎!为了正确理解您的问题:您有一个主函数
    weaveHunks::[a]->[a]->[a]
    (上面的“函数作为其仅有的两个参数是两个列表”),您还有另一个辅助函数,它应该有另一个名称,即
    weaveHunksAux::Int->[a]->[a]
    ,对吗,您对主函数weaveHunks的看法是正确的,它接收两个列表并输出一个列表,该列表是将两个给定列表编织在一起的结果,每次都增加两个给定列表中每个块的大小。辅助函数只是我的想法,我可以通过某种方式保留一个计数器,这样每次都可以增加块的大小,这不是实际问题的一部分。你能通过
    n+1
    和递归调用
    go(n+1)吗lb ab
    ?@ThomasM.DuBuisson:但是下次我们从第一个列表中提取
    3
    元素时,如果我理解正确的话。我们确实可以这样做,并在
    splitAt
    级别与
    2
    相乘。但我不确定这是否会让它更优雅。你对这个问题的理解是正确的,你的解决方案就是我想要达到的。@WillemVanOnsem不需要乘以2
    go n la lb=aa++go(n+1)lb ab,其中(aa,ab)=splitAt n la
    是一个替代品(当然保留基本情况)。试试看。你能用
    go(n+1)lb ab
    传递
    n+1
    和递归调用吗?@ThomasM.DuBuisson:但是下次我们从第一个列表中获取
    3
    元素时,如果我理解正确的话。我们确实可以这样做,并在
    splitAt
    级别与
    2
    相乘。但我不确定这是否会让它更优雅。你对这个问题的理解是正确的,你的解决方案就是我想要达到的。@WillemVanOnsem不需要乘以2
    go n la lb=aa++go(n+1)lb ab,其中(aa,ab)=splitAt n la
    是一个替代品(当然保留基本情况)。试试看。