I've written a function that produces all combinations of elements in a given list:createGroups :: [a] -> [[(a, a)]]createGroups li@(x : xs) = map (\el -> map (\el2 -> (el, el2)) xs) liThese nested maps seem quite messy -- is there a better way to do this?
Producing all possible combinations of a list
haskell
It is possible that I'm misunderstanding the problem, but based on your description, I would expect the type of createGroups to be [a] -> [(a, a)] (A flat list, not a list of lists.)I believe there is bug in your code. Take a look: > createGroups [1..3][[(1,2),(1,3)],[(2,2),(2,3)],[(3,2),(3,3)]]This result is not what I would expect based on your problem description. Given a list of [1, 2, 3], I would expect the output to be [(1,2),(1,3),(2,3)].One way to achieve this output is the following:createGroups :: [a] -> [(a, a)]createGroups [] = []createGroups (x:xs) = map ((,) x) xs ++ createGroups xs> createGroups [1..3][(1,2),(1,3),(2,3)Here is another function that outputs a flat list containing the same pairs as your original function, however it's been rewritten to use list comprehension:createGroups :: [a] -> [(a, a)]createGroups ls @ (_ : xs) = [(x, pair) | x <- ls, pair <- xs]> createGroups [1..3][(1,2),(1,3),(2,2),(2,3),(3,2),(3,3)]Lastly, here is a function that produces output identical to yours, rewritten using the monad instance of list:createGroups :: [a] -> [[(a, a)]]createGroups li@(x : xs) = do  first <- li  return (getPairs first xs)  where    getPairs item pairings = do      pair <- pairings      return (item, pair)> createGroups [1..3][[(1,2),(1,3)],[(2,2),(2,3)],[(3,2),(3,3)]]Hopefully this gives you some ideas of different ways to write your function.