racket - 如何重复应用函数以获得无限序列?
问题描述
例如,
(require racket/generator)
(define f add1)
(define init 0)
(in-producer (generator () (let loop ([x init]) (yield x) (loop (f x)))))
有没有更好的方法来做到这一点?我不太喜欢生成器,因为它们具有隐藏状态。
解决方案
流
使用流可能是最简单的:
(require racket/stream)
;; X [X -> X] -> [Streamof X]
(define (repeated-fn-stream init f)
(stream-cons init (repeated-fn-stream (f init) f)))
(repeated-fn-stream 0 add1)
序列
或者,使用序列和make-do-sequence
:
(require racket/sequence)
;; X [X -> X] -> [Sequenceof X]
(define (repeated-fn-sequence init f)
;; A "Pos" is an X that's the result of applying f repeatedly to init
(define (pos->element pos) pos)
(define (next-pos pos) (f pos))
(define init-pos init)
(make-do-sequence
(λ ()
(values pos->element
next-pos
init-pos
#false
#false
#false))))
(repeated-fn-sequence 0 add1)
如果您想使用序列,并且想使用define-sequence-syntax
使for
循环专门化它:
(这对于“纯”功能是完全没有必要的,但它可能具有不同的性能特征)
(require (for-syntax syntax/parse))
(define-sequence-syntax in-repeated-fn-sequence
(λ () #'repeated-fn-sequence) ; when used as a normal expression
(syntax-parser ; when used *directly* as a for-loop clause
[[(x) (_ init-expr f-expr)]
#'[(x) (:do-in
([(init) init-expr] [(f) f-expr])
#true
([x init])
#true
()
#true
#true
[(f x)])]]))
(for/list ([x (in-repeated-fn-sequence 0 add1)]
[i (in-range 10)])
x)
使用时define-sequence-syntax
,你应该确保每件事都有一个“单点真理”。因此,您经常会看到这种模式:
(define-sequence-syntax in-___
(λ () #'in-___/proc) ; when used as a normal expression
(syntax-parser
....everything that defines the actual functionality....))
;; This is completely determined by the sequence-syntax above,
;; that way there is NO duplicated functionality and NO chance for
;; it to get "out of sync".
(define (in-___/proc parameter ...)
(for/stream ([elem (in-___ parameter ...)])
elem))
这意味着,一旦您决定要使用define-sequence-syntax
,您应该根据它来定义repeated-fn-sequence
函数:
(define (repeated-fn-sequence init f)
(for/stream ([elem (in-repeated-fn-sequence init f)])
elem))
这样,如果in-repeated-fn-sequence
需要更改以修复错误或切换表示,功能版本会自动更改。
推荐阅读
- reactjs - 它不会进入我的循环,但它像条件一样优越
- reactjs - 我不能在 Create React App + node-sass setup 的 sass 文件中使用 @use
- swift - 为什么 DispatchGroup 无法正常工作
- typescript - npm 包与旧版本的包依赖项兼容
- xamarin - Xamarin.forms- 具有多个值的 Firebase 数据库更新 (Android)
- python - 而不是每次输入一个ip如何直接用ip列表读取文件?
- python - 有没有办法在 django 模板中动态编辑值?
- facebook-graph-api - 什么权限可以查看我的 Facebook 页面提要上的共享帖子?
- android - 如何以编程方式设置 Admob appID (19.1.0)?
- laravel - 我收到这个错误。知道如何删除这个 .Creating default object from empty value laravel 5.8