4

I have lists of lists and need to combine it with another list of lists. Example inputs: A: [[1,2],[3,4],[5,6],[7,8]] B: [[1,2],[3,4],[5,6],[7,8]]

Example output: [[1,2,1,2],[1,2,3,4],..,[7,8,5,6],[7,8,7,8]]

2 lists of lists with 4 lists inside both would return us a list of lists size 4*4 = 16

I've tried just recursively combine the lists, but i know it wouldn't work even if would go through.

  mergeAll [[]] [[]] = [[]]
  mergeAll [[]] b = b
  mergeAll a [[]] = a
  mergeAll xs ys = mergeAll (merge xs ys) (drop 1 ys) 

  merge :: [[a]] -> [[a]] -> [[a]]
  merge [[]] [[]] = [[]]
  merge xs [[]] = xs
  merge [[]] ys = ys
  merge (x:xs) (y:ys)  = ((x++y):xs)

kiroyuu
  • 59
  • 5

3 Answers3

4

You can use a list comprehension:

[ xs ++ ys | xs <- listOfLists1, ys <- listOfLists2 ]
chi
  • 111,837
  • 3
  • 133
  • 218
1

You may do like

Prelude> let doit = \as bs -> as >>= \a -> bs >>= \b -> pure (a ++ b)
Prelude> doit [[1,2],[3,4],[5,6],[7,8]] [[1,2],[3,4],[5,6],[7,8]]
[[1,2,1,2],[1,2,3,4],[1,2,5,6],[1,2,7,8],[3,4,1,2],[3,4,3,4],[3,4,5,6],[3,4,7,8],[5,6,1,2],[5,6,3,4],[5,6,5,6],[5,6,7,8],[7,8,1,2],[7,8,3,4],[7,8,5,6],[7,8,7,8]]
Redu
  • 25,060
  • 6
  • 56
  • 76
  • 4
    imo it's cleaner to define it as `doit = liftA2 (++)` - not only is that easier to read and understand (imo, anyway), it makes it clearer that you don't need the `Monad` interface, just the `Applicative` one. – Robin Zigmond Nov 05 '19 at 20:27
  • @Robin Zigmond Yes sure. – Redu Nov 05 '19 at 20:34
0

As Robin says in a comment, you can also do it like:

liftA2 (++)

I ask my self a question trying to understand why that is equivalent to:

[xs ++ ys | xs <- xss, ys <- yss]
developer_hatch
  • 15,898
  • 3
  • 42
  • 75