I suppose just putting in a hash isn't too bad. 

#lang racket
(require racket/generator rackunit)

(define/contract (make-cartesian-generator gens)
  ((listof generator?) . -> . generator?)
  (generator ()
             (define solcache (make-hasheqv))
             (let loop ([gens gens][genidx 0][sols empty])
               (cond
                 [(empty? gens) (yield (reverse sols))]
                 [else 
                  (match-define (cons gen rest) gens)
                  (cond
                    [(eq? (generator-state gen) 'done)
                     (for ([sol (in-list (reverse (hash-ref solcache genidx)))])
                       (loop rest (add1 genidx) (cons sol sols)))]
                    [else
                     (for ([sol (in-producer gen (void))])
                       (hash-update! solcache genidx (λ (vals) (cons sol vals)) 
null)
                       (loop rest (add1 genidx) (cons sol sols)))])]))))

(define g1 (generator () (yield 1) (yield 2) (void)))
(define g2 (generator () (yield 'a) (yield 'b) (void)))

(check-equal? 
 (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))])
   gs)
 '((1 a) (1 b) (2 a) (2 b)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to