Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here. Hi, I found a small exercice: counting all the tuple (x1, x2, x3, x4) whose sum is equal to 18. For that I used list comprehension:

``````allCombination n = [(x1, x2, x3, x4)|
x1 <- lst,
x2 <- lst,
x3 <- lst,
x4 <- lst,
x1 + x2 + x3 + x4 == n]
where lst = [0..n]

main = putStrLn \$ show \$ length (allCombination 18)
``````

Is it possible to be more generic ? Like here I have a tuple of 4 element but would it be possible to have an arbitrary number of element ? For instance via a monad. Something like

``````import Control.Monad

allCombination eltcnt n =  do
newlst <- traverse undefined [0..eltcnt]
guard \$  (sum newlst) == n
where lst = [0..n]

main = putStrLn \$ show \$ length (allCombination 4 18)
``````

Issue is, I'm not sure traverse will work as I expect it to do if I replace `undefined` by `\_-> lst` it doesn't work unfortunatly If you use this guy, you could do it like this:

``````allCombination eltcnt n = do
candidate <- variateRep eltcnt [0..n]
guard (sum candidate == n)
`````` Or more simply:

``````allCombination eltcnt n = filter (\ candidate -> sum candidate == n) (variateRep eltcnt [0..n])
`````` More generally, `replicateM` does the same thing and lives in the `base` library. (Not sure what the advantage of `variateRep` would be. Better handling if `eltcnt` is negative, maybe? Performance?) Yes, I’d do:

``````allCombination n = fmap tuplize \$ filter ((==18) . sum) \$ replicateM 4 [0..n]
where tuplize [a,b,c,d] = (a,b,c,d)
`````` Bernd Losert said:

If you use this guy, you could do it like this:

``````allCombination eltcnt n = do
candidate <- variateRep eltcnt [0..n]
guard (sum candidate == n)
``````

I imagine you could even use it with `MonadComprehensions`, then it looks even more like the original.