1

そのため、プログラミング言語クラスの演習問題に取り組んでおり、課題の 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)))4 ではなく 3 になります。適切な私に知らせてください。

ありがとうございました!

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の代わりに を使用することをお勧めします。carcadrmatch

(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]))

`関連するとが気に入らない人もいますが,、私はすべての よりもそれらを好みlistます。

于 2013-05-22T11:57:44.370 に答える