[英]How can I convert a list of 3-tuples into one 3-triple of lists in Haskell?
我正在尝试编写一个 function 调用,它采用三元组列表并生成三个列表的三元组。 例如,调用[(a,b,c), (d, e, f), (g, h, i)]
的 function 应该产生([a,d,g], [b, e, j], [c, f, i])
。
到目前为止我有这个:
-- This gives the head of a 3-tuple
fst3 :: (a, b, c) -> a
fst3 (x, _, _) = x
unzipTriples :: [(a, b, c)] -> a
unzipTriples (x : y : z : xs) = (fst3 x : fst3 y : fst3 z, unzipTriples xs)
我认为这会创建一个列表 [a, d, g],然后将其添加到 3 元组,并对剩余列表执行 rest。 function这个错误如何改善?
unzipTriples (x: y: z: xs) = …
中的模式(x: y: z: xs)
z: xs) 将采用列表的前三个元素,因此x
、 y
和z
是三元组。 但是您因此会限制自己处理具有三个或更多元素的列表。
您可以做的是使用map
,从而使用:
fst3 :: (a, b, c) -> a
fst3 (a, _, _) = a
snd3 :: (a, b, c) -> b
snd3 (_, b, _) = b
thd3 :: (a, b, c) -> c
thd3 (_, _, c) = c
unzipTriples :: [(a, b, c)] -> ([a], [b], [c])
unzipTriples xs = (map fst3 xs, map snd3 xs, map thd3 xs)
但它可能更优雅,并且当您对列表的第一项(一个 3 元组)进行模式匹配时会消耗更少的 memory,然后在列表的尾部进行递归,因此:
unzipTriples :: [(a, b, c)] -> ([a], [b], [c])
unzipTriples [] = ([], [], [])
unzipTriples ((a, b, c):xs) = (a:as, b:bs, c:cs)
where ~(as, bs, cs) = unzipTriples xs
您可以使用foldr:: Foldable t => (a -> b -> b) -> b -> ta -> b
将其转换为表达式,我将其留作练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.