我很难弄清楚如何将 Int 列表拆分为包含两个新列表的元组,以便每个元素(从第一个列表开始)进入第一个列表,而所有其他元素进入第二个列表。
像这样:
split [] = ([],[])
split [1] = ([1],[])
split [1,2] = ([1],[2])
split [1,2,3] = ([1,3],[2])
split [1,2,3,4] = ([1,3],[2,4])
我正在尝试递归地完成此任务(使用防护)并且仅使用单个参数 xs
这是我不断收到错误消息的方法:
split :: [Int] -> ([Int],[Int])
split xs | length(xs) == 0 = ([],[])
| length(xs) == 1 = (xs !! 0 : [],[])
| length(xs) == 2 = (xs !! 0 : [], xs !! 1 : [])
| otherwise = (fst ++ xs !! 0, snd ++ xs !! 1) ++ split(drop 2 xs))
最佳答案
您的 split
函数返回一对,但在最后一种情况下,您在 split
的结果上使用 ++
。这将是一个类型错误,因为 ++
适用于列表,而不是对。还有一个类型错误,因为 fst
和 snd
是挑选一对元素的函数,但您使用它们的方式很奇怪。
此外,使用模式匹配而不是使用长度。另外,不需要测试长度是否为 2 的情况,因为一般情况会删除 2 个元素,这会将您带到空列表的基本情况。
您还可以通过在类型中使用类型变量 a
而不是 Int
来使函数更加通用。
[编辑]:添加代码
split :: [a] -> ([a], [a])
split [] = ([], [])
split [x] = ([x], [])
split (x:y:xys) = (x:xs, y:ys) where (xs, ys) = split xys
关于list - Haskell:将列表拆分为两个新列表的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7410989/