Mirzhan Irkegulov
Mirzhan Irkegulov

Reputation: 18055

Racket: lexical scope inside for

In Haskell, inside a list comprehension, i can bind expressions to a variable every iteration:

[a | x <- xs, let a = x ^ 2, a >= 25]

How do i bind lexical variables in Racket's for comprehension?

Currently i have this code:

(define (euler4)
  (apply max
         (for*/list ([i (in-range 100 1000)]
                     [j (in-range i 1000)]
                     #:when (string=? (number->string (* i j))
                                      (string-reverse (number->string (* i j)))))
           (* i j))))

I want to bound (* i j) to a variable and replace the expression to it everywhere in function.

Upvotes: 3

Views: 321

Answers (2)

Shawn
Shawn

Reputation: 52344

These days in modern versions of Racket (defined as 8.5 and newer), for comprehensions have a #:do [do-body ...] clause that lets you do things like define variables. So you might write it as

(define (euler4)
  (apply max
         (for*/list ([i (in-range 100 1000)]
                     [j (in-range i 1000)]
                     #:do [(define ij (* i j))
                           (define ij-str (number->string ij))]
                     #:when (string=? ij-str (string-reverse ij-str)))
           ij)))

Upvotes: 1

Eli Barzilay
Eli Barzilay

Reputation: 29546

Use the in-value form to have a loop variable that is bound to a single value.

In your example:

(define (euler4)
  (apply max
         (for*/list ([i (in-range 100 1000)]
                     [j (in-range i 1000)]
                     [ij (in-value (* i j))]
                     #:when (string=? (number->string ij)
                                      (string-reverse (number->string ij))))
           (* i j))))

Upvotes: 9

Related Questions