Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For Loop Construction Turned Functional

I am currently learning Racket and want to do the following simple task: Construct a list which contains all tuples (i,j) : Int * Int with 0 <= i < N and 0 <= j < M.

In, let's say Python, I would immediately know how to approach this, by using for loops:

# Not using any modules on purpose here
a = []
for i in range(5):
    for j in range(6):
        a.append((i,j))     

But I have trouble doing this in Racket. By now I have found a solution which replicates the for-loop approach by using a recursively defined function which for a : A and f : Int -> A -> A satisfies the equations

for 0 a f = (f 0) a
for n a f = for (n-1) ( (f n) a ) f  

which results in a chain of applications: for n a f = ( (f 0) ∘ ... ∘ (f n) )(a). (By f ∘ g I mean composition of f and g). So first f n is applied to a, then f (n - 1) to the result of that, etc.

Given I basically want to do something like ((f 0 0) ∘ (f 0 1) ∘ ... ∘ (f N M)) (a), it can be split up as:

 (((f 0 0) ... (f 0 M)) ∘ ... ∘ ((f N 0) ... (f N M))) (a)
= ((λz. for M z (f 0)) ∘ ... ∘ (λz. for M z (f N))) (a)
= for N a (λi z. for M z (f i))

Which then translates to the following Racket code:

(define (for n a f)   ;; (for n '() cons) = range(n) = (0 1 ... n-1)
    (if (< 0 n) 
        (for (- n 1) (f (- n 1) a) f) 
        a))
        
(define a '())
(define (append i j x) (cons (cons i j) x))

(for 5 a (λ(i x) 
       (for 6 x (λ(j y) 
              (append i j y)))))

The answer produces the desired result and is at least nice regarding that it is obvious how to extend this construction with any number of additional loops.

But I am still wondering whether there isn't a neater functional way to do this.

I'm happy with any answer that does or does not use functions which might already be present in some library and which I have simply missed so far.

like image 365
Léreau Avatar asked May 07 '26 06:05

Léreau


1 Answers

You are probably looking for for*/list:

(for*/list ([i (range 5)]
            [j (range 6)])
  (list i j))

See also Racket guide for Iterations and Comprehensions.

like image 143
Martin Půda Avatar answered May 10 '26 04:05

Martin Půda



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!