TR isn't really good about finding precise types for range sequence
elements. The macro-expanded code is too complicated.
When I write a loop with an index that needs to have a specific, narrow
type, I either use an assertion, as in
(for/list : (Listof Byte) ([b (in-range 256)])
(assert b byte?))
or loop using the next wider type and always compare the loop index with
a value that has the narrow type:
(reverse
(let loop : (Listof Byte) ([b : Index 0]
[bs : (Listof Byte) empty])
(cond [(<= b 255) (loop (+ b 1) (cons b bs))]
[else bs])))
The second method is about 10% faster.
Neil ⊥
On 02/18/2015 02:38 PM, John Clements wrote:
I want to write this:
(for/list ([b (in-range 256)])
b)
... and get back a list of bytes.
That is, I want TR to see that the number 256 is one greater than the
largest byte, and therefore that b must be of type byte. I see that
this dips way too close to undecidability in the general case, so I
would instead perhaps expect to see something like an 'in-bytes-range'
form that is known to produce only bytes.
I looked for such a thing, but didn't find it. Naturally, I could
simply jam a run-time check in at the top of the body, something like
'ensure-bytes', but it seems unnecessary.
Am I missing something obvious?
Thanks!
John
____________________
Racket Users list:
http://lists.racket-lang.org/users
____________________
Racket Users list:
http://lists.racket-lang.org/users