Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permutations of a list - Haskell

Tags:

haskell

monads

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]]
like image 506
RooSoft Avatar asked Jan 08 '12 17:01

RooSoft


1 Answers

What you want is replicateM:

replicateM :: Int -> m a -> m [a]

The definition is as simple as:

replicateM n = sequence . replicate n

so it's sequence on the list monad that's doing the real work here.

like image 121
ehird Avatar answered Nov 16 '22 00:11

ehird