Understanding Lists in Haskell

I used the following code to get all combinations of a predetermined number of numbers:

getList x = [ [a,b,c] | a <- [1..x], b <- [1..x], c <- [1..x]] 

It was good to start with, but I want to expand the program to handle very large lists, and I continue to think that there should be a better way to do this. How to create a function that takes the same parameter x as here, as well as another parameter for the number of elements that have subscriptions. For the four elements, I would go and change the code:

 getList x = [ [a,b,c,d] | a <- [1..x], b <- [1..x], c <- [1..x], d <- [1..x]] 

This should not be a list comprehension. Thanks for any help.

+7
source share
2 answers

I believe that you want to be a replicateM function in Control.Monad .

The list monad is based on the "attempt of all possible combinations", and regular replicate creates the list by repeating the item several times. Thus, the result of replicateM is, given some list of possible values, a list of all possible ways to select an item from this list several times.

For example:

 > replicateM 2 [0, 1] [[0,0],[0,1],[1,0],[1,1]] > replicateM 3 [0, 1] [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]] 

So, to extend your function to arbitrary repetitions, you should use something like:

 getListN nx = replicateM n [1..x] 

... where your original getList will be equivalent to getListN 3 .

+17
source

In case someone likes a non-monadic solution for understanding internal work (although soliution through replicateM excellent!):

 getListN n = foldl (\ass bs -> [ b:as | b <- bs, as <- ass]) [[]] . replicate n 

Essentially, this implementation through foldl works in exactly the same way as the replacatM solution does.

+3
source

All Articles