I want to make all possible combinations of subgroups with 2 lists. Here is a function that does just this:
getCombinations :: [a] -> [[a]]
getCombinations na = do
a <- na
b <- na
[[a,b]]
If you pass "abc" to this function, it returns this:
["aa","ab","ac","ba","bb","bc","ca","cb","cc"]
A simple modification of the same method could return combinations of 3 lists instead of two.
getCombinations :: [a] -> [[a]]
getCombinations na = do
a <- na
b <- na
c <- na
[[a,b,c]]
Result of passing "abc" as an argument:
["aaa","aab","aac","aba","abb","abc","aca","acb","acc",
"baa","bab","bac","bba","bbb","bbc","bca","bcb","bcc",
"caa","cab","cac","cba","cbb","cbc","cca","ccb","ccc"]
What's the simplest way to make it scale to an arbitrary number of lists? Here is what the type declaration should look like:
getCombinations :: Int -> [a] -> [[a]]
For those come here for the combination function, a k-combination of a set S is a subset of k distinct elements of S, note that the order doesn't matter.
Choose
k
elements fromn
elements equals choosek - 1
elements fromn - 1
elements plus choosek
elements fromn - 1
elements.Use this recursive definition, we can write:
The op's question is a repeated permutations, which someone has already given an answer. For non-repeated permutation, use
permutations
from Data.List.What you want is
replicateM
:The definition is as simple as:
so it's
sequence
on the list monad that's doing the real work here.