分开列表haskell的偶数和奇数元素

时间:2018-12-05 17:57:01

标签: haskell

我正在尝试将列表中的元素分成更多列表,一个用于奇数,另一个用于偶数。

例如,

input: [1,2,3,4,10]
output: ([2,4,10],[1,3])

sepList :: [Int]->([Int],[Int])
sepList [] = ([],[])
sepList (x:xs) | (x mod 2) ==0 = (([x],[]) ++ sepList xs) 
               | (x mod 2) /=0 = (([],[x]) ++ sepList xs)
               | otherwise = ([],[])

它在...++ sepList xs上显示错误 有人可以在这里引导我吗?

6 个答案:

答案 0 :(得分:4)

运算符++用于连接2个列表,并且++的自变量都不是列表,

([x],[]) ++ sepList xs

([x],[])sepList xs都是列表对。因此,您要在sepList xs上进行模式匹配,例如使用let绑定

let (ys,zs) = sepList xs in

然后返回,

(x:ys,zs)

答案 1 :(得分:4)

您没有串联两个列表;您要向列表中添加单个元素 ,该列表是从递归调用的元组输出中选择的。不要使用(++);使用(:)

sepList (x:xs) = let (evens, odds) = sepList xs
                 in if even x 
                    then (x:evens, odds)
                    else (evens, x:odds)

更简单地说,sepList = partition even。 (partitionData.List中。)

答案 2 :(得分:2)

到目前为止,有两个答案建议基本上是手动执行此操作(通过对递归调用的结果进行模式匹配),但是实际上已经为要使用的类型定义了一个运算符你想要什么!列表与(<>) = (++)构成一个Monoid,但是您没有两个列表:您有两个个列表。令人高兴的是,如果对中的每个元素都是一个对映体:(a,b) <> (c,d) = (a <> c, b <> d),则对的类型也是一个对映体。因此,您可以简单地将++调用替换为<>,这将导致连接成对的相应列表。

答案 3 :(得分:1)

对于发烧友来说,只需一行以下即可将列表分为偶数和奇数。

sepList xs = (filter even xs , filter odd xs)

答案 4 :(得分:1)

  import Data.List

  sepList :: [Int]->([Int],[Int])
  sepList = partition even

  sepList [1,2,3,4,10]

答案 5 :(得分:0)

在这种情况下,我将使用accumulator创建包含两个列表的元组。在我们的情况下,accumulator([],[])

split::[Int]->([Int],[Int])
split ls= go  ([],[]) ls where 
   go accu [] = accu
   go (odd,even) (x:xs) | x `mod` 2==0 = go (x:odd,even) xs
                        | otherwise = go (odd, x:even) xs

如您所见,由于我们正在使用:运算符将其推入列表的顶部,因此需要反转元素。

我不知道这是否是最佳选择,但是我会这样写:reverse

module Split where
split::[Int]->([Int],[Int])
split ls=let rev tupl=(reverse . fst $ tupl ,reverse .snd $ tupl) in 
             rev $  go ([],[]) ls where 
                    go accu [] = accu
                    go (odd,even) (x:xs) | x `mod` 2==0 = go (x:odd,even) xs
                                         | otherwise = go (odd, x:even) xs