簡體   English   中英

Haskell-使用折疊將成對的列表分成兩個列表

[英]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的元素,可以使用fstsnd而不是通過索引,最后,使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM