【问题标题】:eval scheme function with quote带引号的 eval 方案函数
【发布时间】:2013-03-20 14:42:39
【问题描述】:

我正在尝试评估方案中的公式:

(define formula '(if (or (equal? '?country 'United-States) (equal? '?country 'England))
                  #t
                  #f))
(define (eval-formula formula)
  (eval `(let ([?country 'United-States])
           (display formula) (newline)
           (display ?country) (newline)
           ,formula)))

(eval-formula formula)

阅读http://docs.racket-lang.org/guide/eval.html 应该返回#t,但是当我运行它时,它返回#f。你能告诉我我误解了什么吗?

我也试过了:

(define formula '(if (or (equal? '?country 'United-States) (equal? '?country 'England))
                  #t
                  #f))
(define ?country 'United-States)
(eval formula)

但我得到了相同的结果。

非常感谢!

【问题讨论】:

    标签: scheme let


    【解决方案1】:

    在您对formula 的定义中,您引用了?country - 这是错误的。这是行为(注意,我的 Scheme 的 eval 需要一个额外的 environment 参数):

    (define formula '(if (or (equal? ?country 'United-States) (equal? ?country 'England))
                      #t
                      #f))
    
    (define (eval-formula formula)
      (eval `(let ([?country 'United-States])
               (display formula) (newline)
               (display ?country) (newline)
               ,formula)
        (interaction-environment)))
    
    > (eval-formula formula)
    (if (or (equal? ?country 'United-States) (equal? ?country 'England)) #t #f)
    United-States
    #t
    

    有几件事可以让这变得更好。你真的不需要if(你会得到#t#f作为or的结果)。您可以将附加参数传递给eval-formula 以获取国家/地区名称。像这样(删除display):

    > (define (eval-formula formula country)
      (eval `(let ([?country ',country]) ,formula)
        (interaction-environment)))
    > (eval-formula formula 'United-States)
    #t
    > (eval-formula formula 'England)
    #t
    > (eval-formula formula 'Japan)
    #f
    

    事实上,如果给你formula(quote ?country),那么你可以产生一个新的formula?country 不带引号:

    (define (unquoting identifiers expression)
      (if (null? expression)
          '()
          (let ((next (car expression)))
            (cons (cond ((not (pair? next)) next)
                        ((not (null? next))
                         (if (and (eq? 'quote (car next))
                                  (member (cadr next) identifiers))
                             (cadr next) ; unquote here
                             (unquoting identifiers next)))
                        (else 'error))
              (unquoting identifiers (cdr expression))))))
    
     (set! formula (unquoting '(?country) formula)
    

    【讨论】:

    • 问题是我收到了一些公式和一些变量值(以?开头的变量),我必须返回真或假。我尝试调试它并且它评估: (if (or (equal? (quote ?country) (quote United-States)) (equal? (quote ?country) (quote England))) #t #f) 。我正在尝试删除 ?country 前面的“引用”。
    • 我的问题是如何取消引用 ?country
    • 我能看到它的唯一选项是重写formula 以仅用?country 替换(quote ?country)。如果您尝试重新定义quote,那么该重新定义将应用于(quote United-States)(quote England),并导致评估问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    相关资源
    最近更新 更多