Hello,

I have interest in picking up racket and have done some koans and also have 
been doing the racket track on exercism.

There is a fairly simple exercise called `etl` on exercism related to 
taking a hash for scoring scrabble letters and unpacking it into a flatter, 
more efficient structure for lookups.

The input hash has score as the key and a list of letters of that score as 
the value.  The output is a hash of letter -> score.  One pair per letter 
instead of one pair per score.

It was easy enough to solve with `for-each` using side-effects to update a 
mutable hash, however I think using a generator is a cleaner approach and 
doesn't require mutability.  In python using generators would be very 
straightforward:


def gen(input):
    for score, letters in input.items(): 
        for l in letters: yield l, score 
dict(gen(input))



I am stumbling on the racket solution using generators and I was wondering if I 
could get some pointers from the list.  This could actually be a good candidate 
for the "from python to racket" idioms that is being discussed in a separate 
thread.

I find that the racket docs are lacking in describing generator use cases that 
yield more than one value.  I tried passing `(void)` as a stop value to the 
`in-producer` call but says it needs a predicate when the producer yields more 
than one value.

Also I would assume if the generator is iterating over a finite sequence we 
would not need to define a stop value, but this doesn't seem to work either.

Thanks in advance for any help!

#lang racket

(require racket/generator)

(provide etl
 etl-gen)

(define mixed-case-input (hash 1 '("a" "E" "I" "o" "U" "L" "N" "r" "s" "T")
 2 '("D" "G")
 3 '("B" "c" "M" "P")
 4 '("f" "h" "V" "W" "y")
 5 '("K")
 8 '("J" "x")
 10 '("q" "z")))

 
(define (etl input)
 (define result (make-hash))
 (define/contract (transpose score letters)
 (-> positive? list? any)
 (for-each (lambda (letter)
 (hash-set! result (string-downcase letter) score)) letters))
 (hash-for-each input transpose)
 result)


(define (etl-gen input)
 (define unpack (generator ()
 (for* ([(score letters) input]
 [l letters])
 (yield (string-downcase l) score))))
 (for/hash ([(letter score) (in-producer unpack)]) (values letter score)))




-- 
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