Haskell:将偶数和奇数元素拆分为元组

Haskell:将偶数和奇数元素拆分为元组,haskell,Haskell,我不能使用高阶函数。我只是不知道该怎么做。我对哈斯克尔很陌生。它还必须是递归的 split :: [Int] -> ([Int],[Int]) split xs = 我是从这个开始的。我真的不知道从哪里开始解决这个问题 示例: split [] ([],[]) split [1] ([1],[]) split [1,2,3,4,5,6,7,8,9,10] ([1,3,5,7,9],[2,4,6,8,10]) 任何帮助都将不胜感激 编辑:它的偶数和奇数位置 所以 拆分[3,6,8,

我不能使用高阶函数。我只是不知道该怎么做。我对哈斯克尔很陌生。它还必须是递归的

split :: [Int] -> ([Int],[Int])
split xs = 
我是从这个开始的。我真的不知道从哪里开始解决这个问题

示例:

split []
([],[])

split [1]
([1],[])

split [1,2,3,4,5,6,7,8,9,10]
([1,3,5,7,9],[2,4,6,8,10])
任何帮助都将不胜感激

编辑:它的偶数和奇数位置

所以

拆分[3,6,8,9,10]将是 ([3,8,10],[6,9])

好的,我想到了这个。这并不漂亮,但似乎还可以

split :: [Int] -> ([Int],[Int])
split [] = ([],[])
split [xs] = ([xs],[])
split xs = (oddlist xs, evenlist xs)

oddlist :: [Int] -> ([Int])
oddlist xs | length xs <= 2 = [head(xs)]
           | otherwise = [head(xs)] ++ oddlist(tail(tail(xs)))

evenlist :: [Int] -> ([Int])
evenlist xs | length xs <= 3 = [head(tail(xs))]
            | otherwise = [head(tail(xs))] ++ evenlist(tail(tail(xs)))
split::[Int]->([Int],[Int])
拆分[]=([],[])
拆分[xs]=([xs],])
拆分xs=(oddlist xs,evenlist xs)
oddlist::[Int]->([Int])
oddlist xs |长度xs([Int])

evenlistxs | length xs如果不允许使用高阶列表函数,那么基本上可以使用递归

示例已经给出了您需要满足的情况:

-- Base case:
split [] = …

-- Recurrence:
split (x : xs) = (do something with x) … (split xs) …

既然您现在提出了解决方案,我将这样实施:

split xs = (everyother 0 xs, everyother 1 xs)
      where everyother _ []     = []
            everyother 1 (x:xs) = everyother 0 xs
            everyother 0 (x:xs) = x : (everyother 1 xs)
这意味着列表中的第一项是项0。

我认为它与

不管怎样,这就是我要做的:

ghci> let split ys = let skip xs = case xs of { [] -> [] ; [x] -> [x] ; (x:_:xs') -> x : skip xs' } in (skip ys, skip . drop 1 $ ys)
ghci> split [1..10]
([1,3,5,7,9],[2,4,6,8,10])
或者格式很好:

split xs = (skip xs, skip . drop 1 $ xs)
  where 
  skip [] = []
  skip [x] = [x]
  skip (x:_:xs') = x : skip xs'
如果您放宽“无高阶函数”限制,您可以这样做:

split :: [a] -> ([a],[a])
split = foldr (\x ~(y2,y1) -> (x:y1, y2)) ([],[])
请注意,
~
使模式匹配延迟,因此,
split
可以根据需要生成结果,而无需首先检查整个列表

您可以通过展开
foldr
来重新引入限制:

split :: [a] -> ([a],[a])
split [] = ([],[])
split (x : xs) = (x : y1, y2)
  where
    (y2, y1) = split xs

你的签名有点不对劲…@Konrad:我不知道你的意思。这两个
是不一样的,我忽略了两个基本情况。算了吧……我显然与Haskell失去联系太久了。请看我的原始答案:列表构造函数缺少括号。@Konrad:对,使用单个参数的函数永远不会出现;-)你的例子有点模棱两可,你是指偶数和奇数位置的元素,还是指本身是偶数或奇数的整数?一个更好的例子可能是:
split[1,3,2,5,8]
~>
([1,3,5],[2,8])
哦,是的,对不起,元素位于偶数和奇数位置。@Tom嘿,谢谢。没有注意到。请注意,@Kenny's和我的解决方案解决了不同的问题。正如@Tom在你的问题下面所评论的,由于你的例子模棱两可,所以不清楚这两个解决方案中哪一个适合你的问题。是的,这很好。有趣的想法。我修复了交换的结果,并以预期的方式使事情变得懒惰。
split :: [a] -> ([a],[a])
split [] = ([],[])
split (x : xs) = (x : y1, y2)
  where
    (y2, y1) = split xs