【问题标题】:Simple Nested Evaluations in DrRacketDrRacket 中的简单嵌套评估
【发布时间】:2013-05-17 09:04:20
【问题描述】:

所以我正在为我的编程语言课处理一些练习题,其中一项任务是创建一个脚本“MyEval”,它允许您进行简单的嵌套加法和乘法运算。 因此,例如该程序将能够做到这一点(MyEval '(1 +(3 *4))) 或更深,但不必做减法或超过 2 个数字和一个运算符。所以没那么复杂。但是我的想法很糟糕,我希望得到一些指导。 这就是我目前所拥有的

#lang racket
(define ns (make-base-namespace))
(define (MyEval lis)
  (cond
    [(and ; neither is a list and can be evaluated
     (not(list? (car lis)))
     (not(list? (caddr lis)))
       )
    (eval (cons (cadr lis) (list (car lis) (caddr lis)) ) ns)]

    [(list? (car lis))
     (MyEval (car lis))]

    [(list? (caddr lis))
     (MyEval (caddr lis))]      

   ) ;end of cond
 ) ;end of define

但是你们可能会注意到这只会解决最后一个内括号,所以如果我这样做 (MyEval '(1 + (1 + 2))) 我得到 3,而不是 4。 感谢任何指导或提示,我不知道我的标题有多准确,但如果不合适,请告诉我。

谢谢!

【问题讨论】:

  • 注意:不要使用您环境的底层eval。如果你这样做了,你就误解了这个任务。

标签: lisp scheme racket r5rs


【解决方案1】:

通常一个好的计划是先编写一些单元测试。函数应为某些输出返回的示例。尝试考虑边界或极端情况。例如:

(require rackunit)
(check-equal? (my-eval '(1 + (3 * 4)))
              13)
(check-equal? (my-eval '(20 + 20))
              40)
(check-equal? (my-eval 1) 
              1)

当然,这些最初都会失败。但你的目标是让他们通过。

接下来,您不需要使用eval,也不应该使用。你几乎不想在现实生活中使用eval。 (另外,你练习的重点不是实现(部分)eval 实现的东西吗?)

最后,除非你有禁止它的班级作业,否则我建议使用match 而不是carcadr 等。使用match,很简单:

(define (my-eval x)
  (match x
    [(list lhs '* rhs) (* (my-eval lhs) (my-eval rhs))]
    [(list lhs '+ rhs) (+ (my-eval lhs) (my-eval rhs))]
    [(list) (list)]
    [_ x]))

您还可以对match 模式使用准引用,我通常觉得它更简洁。相当于,这样:

(define (my-eval x)
  (match x
    [`(,lhs * ,rhs) (* (my-eval lhs) (my-eval rhs))]
    [`(,lhs + ,rhs) (+ (my-eval lhs) (my-eval rhs))]
    [`() `()]
    [_ x]))

虽然有些人不喜欢 `s 和 ,s 所涉及的内容,但我更喜欢这些而不是所有 lists。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2019-07-22
    • 1970-01-01
    • 2010-12-28
    相关资源
    最近更新 更多