Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable List Comprehension Length

I'm generating a list of lists via list comprehension, but I have no idea how to make the sub list's length variable by using a parameter. The input for the following is a tuple (first, second) and an Integer z:

z = 1:

[[a] | a <- [first..second]]

z = 2:

[[a, b] | a <- [first..second], b <- [first..second]]

z = 3:

[[a, b, c] | a <- [first..second], b <- [first..second], c <- [first..second]]
like image 564
BullyWiiPlaza Avatar asked Feb 11 '26 14:02

BullyWiiPlaza


1 Answers

You can use replicateM for this task. It's defined as

replicateM :: Monad m => Int -> m a -> m [a]
replicateM n m = sequence (replicate n m)

The connection here is to turn the list comprehension into do notation:

[[a] | a <- [first..second]] == do
    a <- [first..second]
    return [a]

[[a, b] | a <- [first..second], b <- [first..second]] == do
    a <- [first..second]
    b <- [first..second]
    return [a, b]

[[a, b, c] | a <- [first..second], b <- [first..second], c <- [first..second]] == do
    a <- [first..second]
    b <- [first..second]
    c <- [first..second]
    return [a, b, c]

To make it more clear, let's replace [first..second] by m:

do  let m = [first..second]
    a <- m
    b <- m
    c <- m
    return [a, b, c]

So here you can see that m is just getting replicated n times, hence replicateM. Let's see how the types line up too:

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

m ~ []

replicateM_List :: Int -> [a] -> [[a]]

If you need to do this on arbitrary lists, not just repeating the same list, you can just use sequence on it

like image 67
bheklilr Avatar answered Feb 13 '26 17:02

bheklilr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!