List Haskell:从输入列表创建列表元组

List Haskell:从输入列表创建列表元组,list,haskell,split,tuples,List,Haskell,Split,Tuples,我正在尝试设置一些功能来帮助我目前正在进行的项目。我是Haskell的新手,正在努力实现我想要的功能 我有一个列表[a],希望它输出一个由四个不同列表组成的元组([b],[b],[b],[b]),其中列表[a]中的每个项目依次放入输出元组中的下一个列表中。因此,输入列表[a]中的第一个元素进入第一个列表[b],[a]中的第二个元素进入第二个列表[b],[a]中的第三个元素进入第三个列表[b],依此类推。 我尝试使用chunksOf和splitEvery/splitAt,但无法获得正确的输出。我们

我正在尝试设置一些功能来帮助我目前正在进行的项目。我是Haskell的新手,正在努力实现我想要的功能

我有一个列表
[a]
,希望它输出一个由四个不同列表组成的元组
([b],[b],[b],[b])
,其中列表
[a]
中的每个项目依次放入输出元组中的下一个列表中。因此,输入列表
[a]
中的第一个元素进入第一个列表
[b]
[a]
中的第二个元素进入第二个列表
[b]
[a]
中的第三个元素进入第三个列表
[b]
,依此类推。 我尝试使用chunksOf和splitEvery/splitAt,但无法获得正确的输出。我们将非常感谢您的帮助!谢谢

每次“旋转”4元组并将其前置到第一个元素。因此,我们可以通过一个
foldr
模式来实现这一点,该模式如下所示:

toFour :: [a] -> ([a], [a], [a], [a])
toFour = foldr (\a (bs, cs, ds, as) -> (a:as, bs, cs, ds)) ([], [], [], [])
当我们使用无可辩驳的模式时,这是惰性的,因此我们可以例如分配无限列表的元素,然后以获得第二项的前10个元素为例:

Prelude> (\(_, l, _, _) -> take 10 l) (toFour [1..])
[2,6,10,14,18,22,26,30,34,38]
定义

其中
f
是一般解决方案。这给

Prelude> g ['a' .. 'z']
("aeimquy","bfjnrvz","cgkosw","dhlptx") 
签名

Prelude> :t g
g :: [a] -> ([a], [a], [a], [a])

有关:


我认为输出是
[a]>([a],[a],[a],[a])
?因此,使用
[a]
s作为输出,而不是
[b]
s。您能分享一下您的实现吗?是的,我计划更改[a]的每个元素的数据类型,因为它被放置在[b]中相应的插槽中,这就是我在本例中更改名称的原因。然而,对于这个基本的实现,我认为说[a]将输出是正确的,因为我仍然需要将所需的数据类型映射到[a]中的每个元素,因为它被传递到输出元组。这里提出了类似的问题:这个问题是关于两个元组(我猜是两个元组),但一些答案(dave4220和Yitz)可以很容易地扩展到您的情况。@MikaelF谢谢您的链接。同样,使用
foldr(\a~(x,y)->(a:y,x))([],[])
代码片段(也可能是很早就知道的)。要将其扩展到3元组或n元组。。。交换是旋转的,唯一需要决定的是,朝哪个方向(我发现我的一位同事正在处理这个问题,尽管是在计划中。)而且,。这是一个聪明的解决方案!我认为它也可以通过使用列表或序列而不是元组来推广到任意数量的列表<代码>haskell bucket i=未经修剪(++)。fmap反向。foldr f([],复制i[]);其中fx(xs,y:ys)=((x:y):xs,ys);f x(xs,[])=设y:ys=反向xs in([x:y],ys))@ReinHenrichs这绝非第一次出现在SO答案中。我自己在一两个回答中使用了它(或者是在评论中?)。因为我自己没有想到,我总是指出我第一次看到它是在用户“Ed'ka”的F#(或者是ML?)回答中——我记得我被它吓坏了。他的代码是一个两元组的列表,在每一步交换元组;我记得,这是一个很好的练习,用3元组的泛化来找出正确的元组旋转方向(当然,这可以用于任意n个元组)。@ReinHenrichs。(结果我甚至给了那个答案一笔赏金:))结果它在Haskell维基中<代码>地图(取5)。转置3$[1..]的区块因某种原因而出现分歧:必须在
转置
的上方打一个
取3
,以获得适当的惰性。
f n = transpose . chunksOf n
g xs = let [xs1, xs2, xs3, xs4] = f 4 xs in (xs1, xs2, xs3, xs4) 
Prelude> g ['a' .. 'z']
("aeimquy","bfjnrvz","cgkosw","dhlptx") 
Prelude> :t g
g :: [a] -> ([a], [a], [a], [a])
Prelude> :t f
f :: Int -> [a] -> [[a]]