正如uselpa在評論中已經說過的那樣,解決方案將在末尾使用reverse
。擴展後,range
的球拍執行與gen-iter
函數的結果非常相似,除了某些情況下您可能沒有想到。
的range
球拍的實際實現使用(for/list ([i (in-range start end step)]) i)
,但什麼是擴展到實際上相當於
(reverse
(for/fold ([fold-var null])
([i (in-range start end step)])
(cons i fold-var)))
,例外的是它採用了alt-reverse
功能,而不是reverse
,它使用for/fold/derived
更好的錯誤報告。如果你展開,它相當於一些這方面的簡化(刪除不必要的let-values
包裝,錯誤檢查等)
(reverse
(let ([start start] [end end] [inc step])
(let for-loop ([fold-var null] [pos start])
(if (if (>= step 0)
(< pos end)
(> pos end))
(let ([i pos])
(let ([fold-var (cons i fold-var)])
(for-loop
fold-var
(+ pos inc))))
fold-var))))
而得名讓有相當於定義這樣一個輔助功能:(後部分替代let
S和解除幫手range
功能外)
(define (range start end step)
(reverse
(range-reversed null start end step)))
(define (range-reversed fold-var pos end step)
(if (if (>= step 0)
(< pos end)
(> pos end))
(range-reversed
(cons pos fold-var)
(+ pos step)
end
step)
fold-var))
這仍然是從您的解決方案不同,因爲你的解決方案假定step
是積極的,而這一個工程,即使step
爲負。如果step
是肯定的,if條件將是(< pos end)
而不是嵌套的if。
它也使用(< pos end)
您使用(>= pos end)
,但它也切換if情況。如果(< x y)
與(not (>= x y))
相同,這相當於您的解決方案,因爲(if (not a) b c)
相當於(if a c b)
。但是,至少有一種情況我可以想到哪裏不是這樣,start
或end
是+nan.0
。對於這種情況,球拍的range
函數將返回一個空列表,而您的解決方案將進入無限循環。
你可以使用一個隊列:http://rosettacode.org/wiki/Queue/Usage#Racket – coredump
規範的Scheme方式是使用'reverse',我敢說這不會是你的應用程序的瓶頸無論如何。至於Racket如何操作,請使用Dr Racket中的「打開定義文件」。 – uselpa