0

assume there are dynamic number of nested for loop to output all combinations

in this example, there are 3 nested forloop, to generate a list of all combination such as [1,2,3], [1,3,5] etc.

if there are N nested forloop, how to use recursion to do in haskell?

pseudo code

for i from 1 to 5 do
     for j from 1 to 10 do
          if i < j then
          for k from 1 to 50 do
               if j < k then
                  list1 :: [i,j,k]

unfinished forloop has compile error

forloop :: Integer -> Integer -> [a]
forloop n m
    | n == 1 = 1
    | otherwise =  if n > m 
                     then [(forloop n-1 m)] ++ [n]
                     else []

expect a recursive version of function which can be saved in redis like Action type of .net framework

1
  • FYI, your compilation error is probably caused by your syntactic confusion. Function application has the highest precedence, so forloop n-1 m is parsed as (forloop n) - (1 m). Since forloop n is not a number, and 1 is not a function, the type checker will complain. What you meant there was forloop (n-1) m. Commented Oct 5, 2014 at 18:10

2 Answers 2

1

In Haskell, in general, you use the data structures to drive the flow, rather than control structures (like for-loops). In your particular example, a simple list comprehension would address the same case with a single line of code. As you can see below, this single line of code is also very clear in its intentions:

[(i,j,k) | i <- [1..5], j <- [1..10], k <- [1..50], i < j, j < k]

If you didn't want to use list comprehensions, you could still create a very succinct version using structured recursion or, as the last resort, explicit recursion.

I hope this helps.

Sign up to request clarification or add additional context in comments.

7 Comments

I would move i<j before k<-[1..50]. This improves efficiency and is closer to the original imperative loop.
this version need to hard code i, j, k, but it can be more for example, 5 nested, 7 nested, how about function version of it? if want to save function in redis like saving Action type of .net framework
Just define the upper boundary of the list as a variable, like [1..x], where x is defined somewhere else in your program. There is no special reason for the list boundaries to be constants. And you can define the step too, as in [start, step .. end].
how to save this into hedis ?
Is there a reason to test i<j, j<k instead of using the intended ranges, j<-[(i+1)..10], k <- [(j+1)..50]? The latter is easier to understand and also more than twice as efficient.
|
0

Suppose you have a list of range end for each level of nesting. Consider how you are going to generate the lists, if you have a solution for the shorter list of ranges.

solve :: [Int] -> Int -> [[Int]]
solve [] _ = [[]]
solve (r:t) i = [j:s | j <- [i+1..r], s <- solve t j]

2 Comments

after run let aaa3 = solve [] 5 print aaa3 it return empty list, could you show how to use this function? I have written a recursive version of function which has compile error, expect to save it in redis like Action type of .net framework
@Khovanov it looks like a homework. I thought it would help if you tried to understand how this should be used. An example use is solve [5,10,50] 0 to produce the lists for the sample problem in the post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.