【问题标题】:Define-syntax scheme usage定义语法方案使用
【发布时间】:2012-07-03 16:15:22
【问题描述】:

从昨天开始,我一直在尝试为方案编写一个特殊情况语句,该语句将执行以下操作:

(define (sort x)
  (cond ((and (list? x) x) => (lambda (l)
                                (sort-list l)))
        ((and (pair? x) x) => (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p)))
        (else "here")))

我不会使用所有的 and 和 cond 语句,而是:

(define (sort x)
  (scase ((list? x) => (lambda (l)
                                (sort-list l)))
         ((pair? x) => (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p)))
        (else "here")))

到目前为止,我能做的是:

(define (sort x)
  (scase (list? x) (lambda (l)
                      (sort-list l)))
  (scase (pair? x) (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p))))

使用此代码:

(define-syntax scase
  (syntax-rules ()
    ((if condition body ...)
     (if condition
         (begin
           body ...)))))

我现在想做的就是让 scase 语句有多个这样的参数:

(scase ((list? (cons 2 1)) 'here)
       ((list? '(2 1)) 'working))

但我似乎无法弄清楚我该怎么做。也许你们能给我一点帮助?

提前致谢;)

【问题讨论】:

    标签: lisp scheme


    【解决方案1】:

    如果这是学习如何使用语法规则的练习,请忽略此答案。

    我看到了一种简化您开始使用的代码的方法。

    (define (sort x)
      (cond ((list? x)
                (sort-list x))
            ((pair? x)
                (if (> (car x) (cdr x))
                    (cons (cdr x) (car x))
                    x)))
            (else "here")))
    

    由于所有(and (list? x) x) => (lambda l ... 所做的就是查看x 是否是一个列表,然后将l 绑定到x,(因为#f 不是一个列表,并且'() 不是假的,在至少在 Racket 中),您可以跳过所有这些并使用 x。你不需要使用=> 以防万一,在这种情况下它没有帮助。 => 很有用,如果你想做一个测试,如果成功返回有用的东西,否则#f

    现在,如果您想使用宏,那么您需要澄清您希望它做得更好的地方。我认为那个案例已经做了你想要的。你现有的宏只是if,所以我不知道如何扩展它。

    【讨论】:

      【解决方案2】:

      我找到了我的问题的解决方案,这里是:

      (define-syntax cases
        (syntax-rules ()
          ((_ (e0 e1 e2 ...)) (if e0 (begin e1 e2 ...)))
          ((_  (e0 e1 e2 ...) c1 c2 ...)
           (if e0 (begin e1 e2 ...) (cases c1 c2 ...)))))
      

      还是谢谢大家:)

      【讨论】:

      • 如果这回答了你的问题,你应该accept it
      【解决方案3】:

      这是一个解决方案:

      #lang racket
      
      (require mzlib/defmacro)
      
      (define-syntax scase
        (syntax-rules (else)
          ((_ (else body1)) body1)
          ((_ (condition1 body1) (condition2 body2) ...)
           (if condition1
               body1
               (scase (condition2 body2) ...)))))
      
      (define (sort1 x)
        ((scase ((list? x) (lambda (l)
                            (sort l <)))
               ((pair? x) (lambda (p)
                            (if (> (car p) (cdr p))
                                (cons (cdr p) (car p))
                                p)))
               (else (lambda (e) "here")))
         x))
      

      它适用于 DrRacket。我对您的解决方案进行了三处更改。首先,我将您的 sort 过程重命名为 sort1,因为 sort 是内置在方案中的(我在 sort1 中使用过它)。其次,我更改了sort1 本身,以便将给定的输入传递给scase 返回的过程,您将直接得到排序结果。第三,我修改了scase的语法扩展,让它接受else条件。

      >(sort1 (list 3 1 2))
      '(1 2 3)
      
      > (sort1 (cons 2 1))
      '(1 . 2)
      
      > (sort1 'here)
      "here"
      

      我建议你阅读 Kent Dybvig 的“The Scheme Programming Language”。有一整章是关于语法扩展的。

      【讨论】:

      • 呃,你所做的只是重写 cond (没有 => “功能”)。如果您在最终答案中将 scase 替换为 cond ,则该代码有效。如果这就是你正在做的事情,那就直说吧。
      猜你喜欢
      • 2012-03-16
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多