简体   繁体   English

如何将 3 元组列表转换为 Haskell 中的一个 3 元组列表?

[英]How can I convert a list of 3-tuples into one 3-triple of lists in Haskell?

I am attempting to write a function called that takes a list of triples and produces a 3-tuple of three lists.我正在尝试编写一个 function 调用,它采用三元组列表并生成三个列表的三元组。 For instance, the function called on [(a,b,c), (d, e, f), (g, h, i)] should produce ([a,d,g], [b, e, j], [c, f, i]) .例如,调用[(a,b,c), (d, e, f), (g, h, i)]的 function 应该产生([a,d,g], [b, e, j], [c, f, i])

I have this so far:到目前为止我有这个:

-- 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)

I thought this would create a list [a, d, g] and then add it to the 3-tuple and do the rest for the remaining list.我认为这会创建一个列表 [a, d, g],然后将其添加到 3 元组,并对剩余列表执行 rest。 How can I improve this wrong function? function这个错误如何改善?

The pattern (x: y: z: xs) in unzipTriples (x: y: z: xs) = … will take the first three elements of the list, so then x , y and z are 3-tuples. unzipTriples (x: y: z: xs) = …中的模式(x: y: z: xs) z: xs) 将采用列表的前三个元素,因此xyz是三元组。 But you thus would limit yourself to processing lists with three or more elements.但是您因此会限制自己处理具有三个或更多元素的列表。

What you can do is use map and thus work with:您可以做的是使用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)

But it is probably more elegant, and will consume less memory when you pattern match on the first item of the list, a 3-tuple, and then recurse on the tail of the list, so:但它可能更优雅,并且当您对列表的第一项(一个 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

You can convert this into an expression with foldr:: Foldable t => (a -> b -> b) -> b -> ta -> b , I leave this as an exercise.您可以使用foldr:: Foldable t => (a -> b -> b) -> b -> ta -> b将其转换为表达式,我将其留作练习。

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

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