首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >巢内序列:球拍中的序列发生器

巢内序列:球拍中的序列发生器
EN

Code Review用户
提问于 2015-10-07 07:09:28
回答 1查看 110关注 0票数 3

in-nest-sequence是一个序列生成器,它接受函数和初始值,调用当前值的返回值被用作后续值。例如,(in-nest-sequence add1 0)返回序列(0 1 2 3 4 ...)

最近,苏加德要求我编写define-sequence-syntax版本的in-nest-sequence,即基于宏的版本。我决定试一试

代码语言:javascript
复制
#lang racket
(require (for-syntax unstable/syntax))
(provide (rename-out [*in-nest-sequence in-nest-sequence]))

(define in-nest-sequence
  (case-lambda
    [(func init)
     (make-do-sequence
      (thunk (values identity func init #f #f #f)))]
    [(func . inits)
     (make-do-sequence
      (thunk (values (curry apply values)
                     (lambda (args)
                       (call-with-values (thunk (apply func args)) list))
                     inits #f #f #f)))]))

(define-sequence-syntax *in-nest-sequence
  (lambda () #'in-nest-sequence)
  (lambda (stx)
    (syntax-case stx ()
      [[(x ...) (_ func init ...)]
       (unless (= (syntax-length #'(x ...)) (syntax-length #'(init ...)))
         (raise-syntax-error 'in-nest-sequence
                             (format "~a values required" (syntax-length #'(x ...)))
                             stx #'(init ...)))
       (with-syntax ([for-arity (syntax-length #'(init ...))]
                     [(value ...) (generate-temporaries #'(init ...))]
                     [(y ...) (generate-temporaries #'(init ...))])
         #'[(x ...) (:do-in ([(f) func])
                            (unless (procedure-arity-includes? f for-arity)
                              (raise-arity-error f (procedure-arity f) init ...))
                            ([value init] ...)
                            #t
                            ([(x ...) (values value ...)]
                             [(y ...) (f value ...)])
                            #t
                            #t
                            (y ...))])])))

我是一个使用define-sequence-syntax的新手,所以我欣赏所有关于我的代码的风格、性能和/或一般反馈。(有关一些用法示例,请参见原来的职位。)

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-10-07 12:24:15

对于用户遵循语法和函数返回并接收正确数量的值的情况,这很好。

尽早发现错误是一个很好的原则。

考虑一下这个例子:

(in-iterate add1)

在这里,用户提供一个函数add1,该函数具有1,但不提供任何参数。这最终会导致“结果不匹配;”错误,当add1。在早期使用procedure-arity检查是否提供了足够的init值时,可以捕获此错误。提供给用户的错误消息可以是“预期的1初始值,但接收到0”。

*in-iterate中考虑:[(x ...) (_ func init ...)]。在这里,绑定标识符( xs)的数量必须与init表达式的数目相同。如果它们不是,则可以使用以raise-syntax-error作为错误源的stx

一个应该是语法错误(而不是运行时错误)的示例:

代码语言:javascript
复制
(define (add1/2 x y) (values (+ x 1) (+ y 2)))
(for/list ([n     10]
           [(x y) (in-iterate add1/2 0)])
  (list x y))

构造的名称有点偏离。在in-listin-sequence中,我们有模式in-noun,因此表明in-iteration可能更好。然而,iteration有点模糊。也许一个in-nested-sequencein-nest-sequence是基于Mathematica?http://reference.wolfram.com/language/ref/NestList.html中的名称的。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/106806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档