球拍:实现功能(eval t)
racket: implement function (eval t)
我正在尝试实现一个执行以下操作的函数 (eval t):
示例:
(eval '(2 * (1 + 2))) -> 6
(eval '((3 - (4 / 2)) * 2) -> 2
我目前拥有的是:
(define (inner lst)
((cond
((equal? (second lst) '+) +)
((equal? (second lst) '-) -)
((equal? (second lst) '*) *)
((equal? (second lst) '/) /))
(first lst) (third lst)))
(define (eval t)
(cond
((and (number? (first t)) (number? (third t))) (inner t))
((list? (third t)) (eval `(,(first t) ,(second t) ,(inner (third t)))))
((list? (first t)) (eval `(,(inner (first t)) ,(second t) ,(third t))))))
适用于:
(eval '(1 + (1 + 2))) -> 4
(eval '((1 + 1) + (2 + 2))) -> 6
但它不适用于以下情况:
(eval '((1 + 1) + (1 + (1 + 1))))
任何帮助将不胜感激!
这里的诀窍是理解表达式可以采用两种形式:原始数字数据或包含操作的列表。作为伪语法,这意味着每个表达式必须符合以下结构:
expression = number
| ( expression operator expression )
operator = +
| -
| *
| /
这意味着 eval
函数必须能够处理 任一 类型的表达式,因此所有这些都应该有效:
(eval 7) ; => 7
(eval '(1 + 6)) ; => 7
(eval '((2 * 3) + 1) ; => 7
从中可以得出两点:
eval
函数应该能够处理原始数字,而不仅仅是包含运算符的列表。
- 只有两种情况需要在
eval
函数中处理。
这意味着 eval
可能应该采用如下形式:
; eval : expression? -> number?
(define (eval expr)
(cond
[(number? x) ???]
[else ???]))
您实施 eval
的许多不同案例太复杂,没有必要。您不需要检查列表的结构,因为它始终需要以完全相同的方式进行评估:eval
左侧,然后 eval
右侧,然后将两侧与操作结合在一起在中间。之所以可行,是因为如果 eval
可以处理数字,那么 (eval 3)
之类的东西就可以正常工作。
这听起来像是一道作业题,所以我不会透露具体的实现方式,但希望这足以为您指明正确的方向。
我正在尝试实现一个执行以下操作的函数 (eval t):
示例:
(eval '(2 * (1 + 2))) -> 6
(eval '((3 - (4 / 2)) * 2) -> 2
我目前拥有的是:
(define (inner lst)
((cond
((equal? (second lst) '+) +)
((equal? (second lst) '-) -)
((equal? (second lst) '*) *)
((equal? (second lst) '/) /))
(first lst) (third lst)))
(define (eval t)
(cond
((and (number? (first t)) (number? (third t))) (inner t))
((list? (third t)) (eval `(,(first t) ,(second t) ,(inner (third t)))))
((list? (first t)) (eval `(,(inner (first t)) ,(second t) ,(third t))))))
适用于:
(eval '(1 + (1 + 2))) -> 4
(eval '((1 + 1) + (2 + 2))) -> 6
但它不适用于以下情况:
(eval '((1 + 1) + (1 + (1 + 1))))
任何帮助将不胜感激!
这里的诀窍是理解表达式可以采用两种形式:原始数字数据或包含操作的列表。作为伪语法,这意味着每个表达式必须符合以下结构:
expression = number | ( expression operator expression ) operator = + | - | * | /
这意味着 eval
函数必须能够处理 任一 类型的表达式,因此所有这些都应该有效:
(eval 7) ; => 7
(eval '(1 + 6)) ; => 7
(eval '((2 * 3) + 1) ; => 7
从中可以得出两点:
eval
函数应该能够处理原始数字,而不仅仅是包含运算符的列表。- 只有两种情况需要在
eval
函数中处理。
这意味着 eval
可能应该采用如下形式:
; eval : expression? -> number?
(define (eval expr)
(cond
[(number? x) ???]
[else ???]))
您实施 eval
的许多不同案例太复杂,没有必要。您不需要检查列表的结构,因为它始终需要以完全相同的方式进行评估:eval
左侧,然后 eval
右侧,然后将两侧与操作结合在一起在中间。之所以可行,是因为如果 eval
可以处理数字,那么 (eval 3)
之类的东西就可以正常工作。
这听起来像是一道作业题,所以我不会透露具体的实现方式,但希望这足以为您指明正确的方向。