Sha*_*abu 5 haskell split list
我很难弄清楚如何将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])
Run Code Online (Sandbox Code Playgroud)
我试图以递归方式(使用警卫)并仅使用单个参数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))
Run Code Online (Sandbox Code Playgroud)
aug*_*tss 14
你的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
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用相互递归.它很容易阅读:
split xs = (odds xs, evens xs)
odds (x:xs) = x : evens xs
odds xs = []
evens xs = odds (drop 1 xs)
Run Code Online (Sandbox Code Playgroud)