gpt4 book ai didi

haskell - 如何从两个列表创建列表以及这些列表中的元素

转载 作者:行者123 更新时间:2023-12-02 09:22:04 26 4
gpt4 key购买 nike

我是 Haskell 新手。我正在尝试使用递归来编写一个函数,给定两个列表(它们需要具有相同的类型),交错它们的元素(在第一个和第二个列表之间交替获取元素)。当其中一个列表中不再有元素时,它会停止,结果是到目前为止所达到的列表。

interChange :: [a] -> [b] ->[(a,b)]
interChange _ [] = []
interChange [] _ = []
interChange (x:xs) (y:ys) = (x,y) : interChange xs ys

我的输出示例:

interChange [1,2,3] [4,5,6]
[(1,4),(2,5),(3,6)]

所需输出的示例是:

interChange [1,2,3] [4,5,6]
[1,4,2,5,3,6]

感谢您的帮助

最佳答案

您的 interChange 与 Prelude 的 zip 相同.

ghci> zip [1,2,3] ["wibble", "wobble", "wubble"]
[(1,"wibble"),(2,"wobble"),(3,"wubble")]

为了编写您指定的函数,您实际上需要一对相同类型的列表。我们正在输出特定类型的列表,因此进入该列表的所有元素也必须具有该类型。

interleave :: [a] -> [a] -> [a]

您可以通过传递一个 Bool 来以递归方式实现此目的,指示您应该从哪个列表中获取下一个元素:

interleave = go True
where go _ [] ys = ys
go _ xs [] = xs
go True (x:xs) ys = x : go False xs ys
go False xs (y:ys) = y : go True xs ys

go的最后两个子句之间进行乒乓评估,直到其中一个输入列表为空,然后我们只返回另一个输入列表的其余部分。 (如果您希望它的行为更像 zip ,您可以通过返回 [] 而不是 xsys 来截断输出 在这些情况下。)


但我始终建议尽可能避免在更高级别进行递归编程。我们可以将此函数编写为管道:

  1. 使用 zip 将输入列表的元素配对
  2. 将结果列表中的每个元组转换为二元素列表:map (\(x, y) -> [x, y])
  3. 使用 concat 展平生成的列表列表

所以代码如下所示:

interleave xs ys = concat $ map (\(x, y) -> [x, y]) $ zip xs ys

我发现这段代码比递归代码更容易理解,递归代码需要您推理控制流 - 它只是一系列高级指令。

顺便说一句,您可以通过将中间map拖到concatzip中来省略它:

interleave xs ys = concatMap (\(x, y) -> [x, y]) $ zip xs ys
interleave xs ys = concat $ zipWith (\(x, y) -> [x, y]) xs ys

关于haskell - 如何从两个列表创建列表以及这些列表中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41792586/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com