Haskell: create a tuple of lists from an input list

夙愿已清 提交于 2021-01-05 04:16:38

问题


I am trying to set up some functions to help with a current project I am working on. I am new to Haskell and struggling to implement my desired functions.

I have a list [a] and would like it to output a tuple of four different lists ([b],[b],[b],[b]) where each item in list [a] is successively placed in to the next list in the output tuple. So the first element in the input list [a] goes to the first list [b], the second element in [a] goes to the second list [b], the third element in [a] goes to the third list [b], and so on. I have tried using chunksOf and splitEvery/splitAt but cannot get the correct output. And help would be greatly appreciated! Thanks!


回答1:


You each time "rotate" the 4-tuple and prepend to the first element. So we can implement this with a foldr pattern that looks like:

toFour :: [a] -> ([a], [a], [a], [a])
toFour = foldr (\a (bs, cs, ds, as) -> (a:as, bs, cs, ds)) ([], [], [], [])

or with an irrefutable pattern:

toFour :: [a] -> ([a], [a], [a], [a])
toFour = foldr (\a ~(bs, cs, ds, as) -> (a:as, bs, cs, ds)) ([], [], [], [])

So here (bs, cs, ds, as) is the 4-tuple that we generated for the tail of the list, and we "rotate" to the right to construct the tuple (as, bs, cs, ds) and then prepend the item a to the first list of the 4-tuple.

For a list of integers, this gives us:

Prelude> toFour [1..2]
([1],[2],[],[])
Prelude> toFour [1..3]
([1],[2],[3],[])
Prelude> toFour [1..4]
([1],[2],[3],[4])
Prelude> toFour [1..5]
([1,5],[2],[3],[4])
Prelude> toFour [1..6]
([1,5],[2,6],[3],[4])
Prelude> toFour [1..10]
([1,5,9],[2,6,10],[3,7],[4,8])

When we work with the irrefutable pattern, this is done lazily, so we can for example distribute elements of an infinite list, and then take for example obtain the first 10 elements of the second item:

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



回答2:


Define

f n = transpose . chunksOf n
g xs = let [xs1, xs2, xs3, xs4] = f 4 xs in (xs1, xs2, xs3, xs4) 

Where f is the general solution. This gives

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

Signatures

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

and

Prelude> :t f
f :: Int -> [a] -> [[a]]

Info on:

  • transpose.
  • chunksOf.


来源:https://stackoverflow.com/questions/60685978/haskell-create-a-tuple-of-lists-from-an-input-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!