简体   繁体   English

Haskell-使用折叠将成对的列表分成两个列表

[英]Haskell - separate a list of pairs in two lists using fold

So, I am given a list containing tuples and I need to break it down into two lists, the first list containing the elements with odd index and the second list containing the elements with even index, must be done using fold, here is my attempt: 因此,我得到了一个包含元组的列表,我需要将其分解为两个列表,第一个列表包含具有奇数索引的元素,第二个列表包含具有偶数索引的元素,必须使用fold完成,这是我的尝试:

breakList :: [(Integer, Integer)] -> [[(Integer, Integer)]]
breakList [] = [[], []]
breakList xxs@(x:xs) = foldl (\ acc y -> if length (acc !! 0) < length (acc !! 1) then y : (acc !! 0) else y : (acc !! 1)  )  [[], []] xxs

Error I am getting: 我得到的错误:

Couldn't match type '(Integer, Integer)' with '[(Integer, Integer)]' Expected type: [[(Integer, Integer)]] 无法将类型'((Integer,Integer)]'与'[(Integer,Integer)]'相匹配预期类型:[[(Integer,Integer)]]

when hovering over y : (acc !! 1) and y : (acc !! 0) 将鼠标悬停在y : (acc !! 1) and y : (acc !! 0)

Example: 例:

Input: 输入:

ex1 = [ (2, 2), (1, 3), (2, 3), (2, 4), (3, 5), (0, 2), (2, 1), (1, 4) , (2, 0), (1, 2), (3, 1), (1, 0)] ex1 = [(2,2),(1,3),(2,3),(2,4),(3,5),(0,2),(2,1),(1,4) ,(2,0),(1、2),(3,1),(1,0)]

Output 输出量

breakList ex1 == ( [(2,2),(2,3),(3,5),(2,1),(2,0),(3,1)] , [(1,3),(2,4),(0,2),(1,4),(1,2),(1,0)]) breakList ex1 ==([[(2,2),(2,3),(3,5),(2,1),(2,0),(3,1)],[(1,3), (2,4),(0,2),(1,4),(1,2),(1,0)])

Note that you want to split a list into two lists of a pair, so the return type should be 请注意,您要将一个列表分成两个成对的列表,因此返回类型应为

([(Integer, Integer)], [(Integer, Integer)])

not

[[(Integer, Integer)]]

and access the element of pair, you can use fst and snd instead of through index, and finally, use foldl will return the resulted list in reversed order, it can be fixed use foldr instead. 并访问pair的元素,可以使用fstsnd而不是通过索引,最后,使用foldl将以相反的顺序返回结果列表,可以使用foldr进行固定。 The correction look like: 更正如下所示:

breakList :: [(Integer, Integer)]->([(Integer, Integer)], [(Integer, Integer)])
breakList xxs = foldr (\y acc-> if length (fst acc) < length (snd acc)
                                then (y:(fst acc), snd acc)
                                else (fst acc, y:(snd acc)) ) ([], []) xxs

The standard trick here, as hinted at by Willem in the comments, which I first saw few years back on SO in an (F# or Ocaml) answer by [user:Ed'ka], is 正如Willem在评论中所暗示的,这里的标准技巧是[user:Ed'ka]在(F#或Ocaml)答案中对SO的回想。

evenodds :: [a] -> ([a], [a])
evenodds xs = foldr g ([],[]) xs
  where
  g x ~(as,bs) = (bs,x:as)

or 要么

oddevens :: [a] -> ([a], [a])
oddevens xs = foldr g ([],[]) xs
  where
  g x ~(bs,as) = (x:as,bs)

What are odd positions from here, are even positions from the position one notch further on the list. 从这里开始的奇数位置是从列表上的第一位开始的偶数位置。

The tilde ~ introduces a lazy pattern so that the function is properly lazy in its operations. 代字号~引入了惰性模式,以便该函数在其操作中正确地处于惰性状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM