1

所以我正在为我的编程语言课做一些练习题,其中一项任务是创建一个脚本“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。感谢任何指导或提示,我不知道我的标题有多准确,但如果不是合适的请告诉我。

谢谢!

4

1 回答 1

5

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

(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。

于 2013-05-22T11:57:44.370 回答