[英]Haskell - separate a list of pairs in two lists using fold
因此,我得到了一个包含元组的列表,我需要将其分解为两个列表,第一个列表包含具有奇数索引的元素,第二个列表包含具有偶数索引的元素,必须使用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
我得到的错误:
无法将类型'((Integer,Integer)]'与'[(Integer,Integer)]'相匹配预期类型:[[(Integer,Integer)]]
将鼠标悬停在y : (acc !! 1) and y : (acc !! 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)]
输出量
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)])
请注意,您要将一个列表分成两个成对的列表,因此返回类型应为
([(Integer, Integer)], [(Integer, Integer)])
不
[[(Integer, Integer)]]
并访问pair的元素,可以使用fst
和snd
而不是通过索引,最后,使用foldl
将以相反的顺序返回结果列表,可以使用foldr
进行固定。 更正如下所示:
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
正如Willem在评论中所暗示的,这里的标准技巧是[user:Ed'ka]在(F#或Ocaml)答案中对SO的回想。
evenodds :: [a] -> ([a], [a])
evenodds xs = foldr g ([],[]) xs
where
g x ~(as,bs) = (bs,x:as)
要么
oddevens :: [a] -> ([a], [a])
oddevens xs = foldr g ([],[]) xs
where
g x ~(bs,as) = (x:as,bs)
从这里开始的奇数位置是从列表上的第一位开始的偶数位置。
代字号~
引入了惰性模式,以便该函数在其操作中正确地处于惰性状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.